skip to content

In a Flutter app where `flutter_localizations` needs `intl ^0.20.3` but an older package allows only `intl ^0.19.0`, how do you diagnose and fix the version-solving failure?

level: seniorimportance: should knowfreq 40%

answer

  1. read the Because chain bottom-up
  2. one version per package
  3. pub deps shows who asks
  4. pub outdated Resolvable column
  5. override is the last resort

basics

~20 s

Pub needs one intl version for the whole graph, and ^0.20.3 and ^0.19.0 do not overlap. Read the Because chain, confirm with dart pub deps, then upgrade or replace the lagging package; a dependency override is only a temporary, tested last resort.

solid answer

~40 s

Pub resolves **one version per package** for the whole graph. In Flutter 3.47, `flutter_localizations` (from the Flutter SDK) depends on `intl: ^0.20.3`, which means `>=0.20.3 <0.21.0`; a package allowing only `^0.19.0` (`<0.20.0`) has no overlap, so pub prints a chain of "Because … depends on …" lines ending in **"version solving failed"**. Diagnose by reading that chain for the two conflicting constraints, running `dart pub deps` to see who pulls `intl`, and `dart pub outdated` to see whether a newer release of the lagging package is **resolvable**. Fix in order of preference: upgrade that package (raise its constraint, or `dart pub upgrade --major-versions`), replace it, or contribute a constraint bump upstream. Forcing `intl` with a dependency override is a **last resort**, documented and tested, because the old package never declared support for 0.20.

code

bash · 8 lines
bash
# Who depends on intl, and at which versions?
dart pub deps -s list

# Is a newer old_date_picker resolvable with everything else?
dart pub outdated

# Preview lifting upper bounds before editing pubspec.yaml
dart pub upgrade --major-versions --dry-run

go deeper

for a junior

Know that pub picks one version of each package and fails when two constraints do not overlap.

for a middle

Read the Because chain to find the shared package and the two clashing constraints, and use pub deps to see who pulls it in.

for a senior

Choose the fix deliberately: upgrade or replace the lagging package first, and treat overrides as temporary, tested exceptions.

for a principal

Set package-selection and upgrade-cadence rules that keep SDK upgrades from surfacing large, blocking dependency conflicts.

## Why pub cannot just use both Pub's solver picks exactly **one version of each package** for the entire graph, since every library in the program imports the same `package:intl`. Each constraint on a package narrows the set of acceptable versions, and resolution fails when the intersection is empty. In this scenario: | Who asks | Constraint | Allows | |---|---|---| | `flutter_localizations` (Flutter 3.47 SDK) | `intl: ^0.20.3` | `>=0.20.3 <0.21.0` | | `old_date_picker` | `intl: ^0.19.0` | `>=0.19.0 <0.20.0` | Because both are **pre-1.0** carets, each stops at the next minor, so they do not overlap at all. Pub first tries older versions of `old_date_picker` looking for one with a compatible constraint; only when none exists does it give up. ## Reading pub's error The failure is printed as a derivation, a series of **"Because …"** sentences explaining which constraints combine into the contradiction, ending with **"version solving failed"**. For example: ```text Because old_date_picker >=2.0.0 depends on intl ^0.19.0 and every version of flutter_localizations from sdk depends on intl ^0.20.3, old_date_picker >=2.0.0 is incompatible with flutter_localizations from sdk. So, because my_app depends on both flutter_localizations from sdk and old_date_picker ^2.0.0, version solving failed. ``` Read it for three facts: the **shared package** (`intl`), the **two constraints** that clash, and **which of your direct dependencies** brings each in. The package you control least is usually the one to move. ## Diagnosing with pub's tools 1. **`dart pub deps`** prints the resolved graph as a tree (or `-s list` / `-s compact`), showing which direct dependency pulls in which transitive one. It needs a successful resolution, so run it on the last good state or after temporarily removing the new dependency. 2. **`dart pub outdated`** shows, per package, the **Resolvable** column: the newest version that could be used with everything else if your constraints were unbounded. If a newer `old_date_picker` is resolvable, a newer release already accepts `intl` 0.20. 3. The package's **changelog** on pub.dev confirms which release widened its `intl` constraint. ## Fixes, in order 1. **Upgrade the lagging package.** Raise your constraint on `old_date_picker` to the release that supports `intl` 0.20, or run `dart pub upgrade --major-versions`, then re-test the screens that use it. 2. **Replace it** if it is unmaintained, or use Flutter's own date pickers. 3. **Fix upstream**: a pull request that widens its `intl` constraint after testing. 4. **Downgrade the other side** only when you can: here that means an older Flutter SDK, which is rarely acceptable. 5. **Last resort: a dependency override** on `intl` in the app's root pubspec. It makes the solve succeed, but `old_date_picker` then runs against an `intl` it never declared support for. Keep it temporary, comment why, test the affected code paths, and remove it when upstream catches up. ## Prevention - Prefer maintained packages with wide, current constraints. - Upgrade regularly with `dart pub outdated`, so a single Flutter upgrade does not surface a year of drift at once. - When upgrading Flutter, run `dart pub get` and read any solver output before merging.

  • In Dart's pub, why can't the app load `intl` 0.19 for one package and 0.20 for another?
    A Dart program has one `package:intl` URI, so there is one library of that name in the program. Pub therefore resolves a single version per package for the whole graph, and every constraint on it must be satisfied by that one version.
  • `dart pub outdated` shows `old_date_picker` with Upgradable 2.4.0 and Resolvable 3.1.0. What does that tell you?
    Your current constraint allows up to 2.4.0, but a newer major, 3.1.0, would resolve with everything else if you raised the constraint. Edit the pubspec to `^3.1.0` or use `dart pub upgrade --major-versions`, then check the changelog for breaking changes.

saying these in an interview costs you the question

  • Pub can install two intl versions side by side for different packages
  • The fix is always to add a dependency override
  • pub upgrade will eventually resolve it without changing constraints
  • dart pub deps works even when resolution currently fails
  • Deleting pubspec.lock fixes version solving failures