Start Debugging

Исправление: Version solving failed в pubspec.yaml

Исправление за 30 секунд: прочитайте цепочку 'because' в ошибке, найдите единственное ограничение, которое загоняет pub в тупик, и либо расширьте его, либо добавьте запись в dependency_overrides. Не начинайте с flutter clean.

Исправление в одно предложение: Version solving failed это не баг, а dart pub сообщает вам, что ограничения, которые вы написали в pubspec.yaml, не могут быть удовлетворены все одновременно. Прочитайте цепочку строк because ... depends on ... снизу вверх, найдите одно ограничение, которое невозможно удовлетворить (обычно нижняя граница SDK Dart или пакет, закреплённый на версии более старой, чем требуется одному из его потребителей), а затем либо расширьте это ограничение, либо добавьте запись в dependency_overrides, чтобы принудительно использовать конкретную версию. flutter clean и удаление pubspec.lock это не исправят.

Resolving dependencies...
Because every version of flutter_test from sdk depends on collection 1.19.0
        and my_app depends on collection ^1.18.0, flutter_test from sdk is forbidden.
So, because my_app depends on flutter_test any from sdk, version solving failed.

pub get failed (1; So, because my_app depends on flutter_test any from sdk,
version solving failed.)
exit code 1

Это руководство написано против Dart 3.11 и Flutter 3.41.5, канал stable по состоянию на май 2026. Поведение резолвера, описанное ниже, это тот же алгоритм PubGrub, который поставляется в dart pub начиная с Dart 2.10, поэтому всё здесь применимо без изменений к любому проекту Flutter 3.x или Dart 3.x. Соответствующий исходный код находится в dart-lang/pub в lib/src/solver/.

Что на самом деле означает эта ошибка

dart pub get запускает резолвер в стиле SAT под названием PubGrub. Он обходит каждое ограничение в вашем pubspec.yaml, включая транзитивные ограничения, извлечённые из собственного pubspec.yaml каждой зависимости, и пытается найти один набор версий пакетов, в котором каждое ограничение удовлетворяется одновременно. Когда такого набора не существует, он не сдаётся после одной попытки. Он откатывается, узнаёт факт о том, какие комбинации невозможны, и пробует снова. Вывод, который вы видите, это объяснение доказательства того, что решения не существует.

Каждая строка это факт. Читайте снизу вверх: нижняя строка это вывод (version solving failed), а строки над ней это цепочка фактов, которая вынудила этот вывод. Факт на вершине цепочки это ограничение, которое вы на самом деле написали, и вероятно то, которое вам нужно изменить.

Сообщение об ошибке структурировано. Pub называет каждый релевантный пакет, печатает точное ограничение и сообщает вам, кто его требует. Угадывать не надо, как только вы замедлитесь и прочтёте.

Минимальное воспроизведение, демонстрирующее сбой

Создайте свежий пакет и закрепите две зависимости, чьи транзитивные ограничения противоречат друг другу:

# pubspec.yaml, Flutter 3.41.5, Dart 3.11
name: my_app
environment:
  sdk: '>=2.17.0 <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^1.5.0
  some_legacy_package: 0.4.2

Запустите flutter pub get и получите:

Because http >=1.0.0 requires SDK version >=3.0.0 <4.0.0
        and my_app requires SDK version >=2.17.0 <3.0.0, http >=1.0.0 is forbidden.
So, because my_app depends on http ^1.5.0, version solving failed.

Это наиболее распространённая форма ошибки в реальных проектах. Ограничение, которое ломает разрешение, это ваша собственная нижняя граница SDK. Пакет, который вы запросили, в порядке; SDK, который вы заявили о поддержке, и есть невозможная часть.

Вторая распространённая форма это транзитивное столкновение:

Because flutter_test from sdk depends on collection 1.19.0
        and riverpod 3.0.0 depends on collection ^1.18.0,
        flutter_test from sdk is incompatible with riverpod 3.0.0.
So, because my_app depends on both flutter_test from sdk and riverpod ^3.0.0,
version solving failed.

Тот же алгоритм, другая причина. Здесь пин SDK от flutter_test точный (1.19.0), а riverpod примет что угодно от 1.18.0 до, но не включая, 2.0.0. Оба могут быть удовлетворены, если вы обновите riverpod до версии, чья нижняя граница collection это 1.19.0 или выше. Исправление в версии, которую вы выбираете, а не в синтаксисе ограничения.

Исправление, в порядке частоты, с которой оно является ответом

Выполняйте шаги ниже по порядку. Не перепрыгивайте. Каждый шаг предполагает, что предыдущий не разрешил ошибку.

1. Прочитайте ошибку и определите узкое место

Откройте вывод терминала. Найдите первую строку Because ... и ограничение, названное в самом верху цепочки. Это невозможный факт. В примере с SDK выше это my_app requires SDK version >=2.17.0 <3.0.0. В транзитивном примере это flutter_test from sdk depends on collection 1.19.0.

Запишите две вещи:

  1. Пакет, чьё ограничение не может быть удовлетворено (жертва).
  2. Ограничение, которое его загоняет в угол (виновник).

Если вы не можете определить оба, значит, вы недостаточно внимательно прочитали цепочку. Перечитайте.

2. Поднимите нижнюю границу вашего SDK

В 2026 году наиболее распространённая причина это устаревшее ограничение SDK. Любой пакет, опубликованный за последние 18 месяцев и использующий возможности Dart 3 (records, patterns, sealed classes, новые выражения switch), установит своё ограничение SDK на ^3.0.0. Если ваш pubspec.yaml всё ещё говорит >=2.17.0 <3.0.0, вы не сможете установить этот пакет. Обновитесь до синтаксиса caret против версии Dart, которая у вас реально есть:

# pubspec.yaml, after running `dart --version`
environment:
  sdk: ^3.0.0
  flutter: '>=3.10.0'

Используйте ^3.0.0 (всё от 3.0.0 до, но не включая, 4.0.0), а не ^3.11.0. Нижняя граница сообщает “это самый старый Dart, против которого я тестировал”; установка её равной версии на вашем ноутбуке заставляет каждого участника обновляться без причины. См. документацию pubspec по синтаксису.

3. Обновите конфликтующую зависимость

Если виновник это сторонний пакет, второе по частоте исправление в том, что вы закреплены на старой major-версии. flutter pub outdated показывает вам каждую зависимость, какая версия разрешена и какая самая последняя:

# Flutter 3.41.5
flutter pub outdated

Найдите пакет, названный в шаге 1. Если его столбец latest выше того, что у вас, выполните:

flutter pub upgrade --major-versions <package_name>

Это переписывает ограничение в pubspec.yaml на последнюю совместимую major-версию, а затем повторно запускает резолвер. Если пакет следует semver, вам может потребоваться исправить ломающие изменения в вашем коде, но ошибка резолвера исчезает.

4. Ослабьте слишком жёсткое ограничение

Если вы написали ограничение вручную и зафиксировали его строже, чем нужно, расширьте. Две наиболее частые ошибки переусердствования в закреплении:

# Слишком жёстко: точный пин
some_package: 1.5.3

# Слишком жёстко: caret на pre-1.0 версии
some_package: ^0.4.2  # разрешает >=0.4.2 <0.5.0, часто слишком узко

Замените caret на major-версию (^1.5.3 разрешает >=1.5.3 <2.0.0) или явным диапазоном, который покрывает версии, которые вы готовы принять ('>=0.4.0 <0.6.0'). Документация Dart по ограничениям зависимостей объясняет синтаксис caret как для pre-1.0, так и для post-1.0 пакетов.

5. Используйте dependency_overrides для транзитивных конфликтов, которые вы не можете исправить

Когда виновник это транзитивная зависимость, по которой две ваши прямые зависимости не согласуются, и ни у одной нет релиза, который разрешал бы конфликт, переопределите её явно. Это идёт только в pubspec.yaml корневого пакета; переопределения в зависимости, которую вы потребляете, игнорируются резолвером.

# pubspec.yaml, Flutter 3.41.5, Dart 3.11
name: my_app
environment:
  sdk: ^3.0.0

dependencies:
  flutter:
    sdk: flutter
  riverpod: ^3.0.0
  some_other_package: ^2.0.0

dependency_overrides:
  collection: ^1.19.0

dependency_overrides это кувалда. Резолвер прекращает применять ограничения к переопределённому пакету и использует вашу версию везде, где он появляется в графе. Если потребитель collection полагался на удалённый в 1.19.0 API, он скомпилируется, но упадёт в среде выполнения. Используйте это только после того, как убедились, что версия, которую вы форсируете, действительно совместима, и удалите переопределение в момент, когда upstream-зависимость нагонит.

6. Крайнее средство: пересоздать pubspec.lock

Lockfile находится ниже по потоку от разрешения, а не выше. Удаление его не может исправить проблему ограничений, и большинство постов в блогах, которые рекомендуют это в качестве первого шага, неправы. Единственный случай, когда удаление pubspec.lock помогает, это если вы уже изменили pubspec.yaml, а lockfile теперь блокирует резолвер от выбора новой совместимой версии:

# Flutter 3.41.5
rm pubspec.lock
flutter pub get

Делайте это только после шагов 1-5. Если pub get всё ещё падает после пересоздания lockfile, ограничения по-прежнему невозможны, и вы ничего на самом деле не исправили.

Подводные камни и похожие случаи

Несколько случаев, которые производят похожую ошибку или выглядят как разрешение версий, но таковыми не являются:

Если вы тянетесь к dependency_overrides чаще, чем раз в квартал, ваше дерево зависимостей имеет структурные проблемы. Либо вы используете слишком много пакетов из одного микро-домена (три HTTP-клиента, два менеджера состояния), либо ваши прямые зависимости не успевают за своими собственными транзитивными. Подрезка дерева исправляет больше ошибок резолвера, чем любая отдельная правка ограничения.

Связанное

Источники

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад