Disclaimer: This is one of those articles that you’ll really want to read until to the very end.

The more you play around with Flutter and introduce new dependencies in your project, the more likely it is to run into a dependency conflict at some point. Especially around the time when significant updates happen.

Chances are, sooner or later you’ll encounter something like this:

Because intl_translation 0.17.0 depends on petitparser ^1.1.3 and xml >=3.2.0 depends on petitparser ^2.0.0, intl_translation 0.17.0 is incompatible with xml >=3.2.0.

So, because my_project depends on both xml ^3.2.0 and intl_translation 0.17.0, version solving failed.

From the error message, it’s clear that these versions of the xml and intl_translation packages don’t play together nicely. Since those packages depend on a different major version of petitparser, there’s an unresolvable dependency version conflict here.

The pubspec file might look a little something like this:

pubspec.yaml
dependencies:
  # ...
  xml: ^3.2.0
  intl_translation: ^0.17.0

Although we could go to pub.dartlang.org and find the compatible versions manually by trial and error, we don’t have to. There’s something that’s made exactly for that. It’s also built into Pub and way faster than we could ever be.

#The solution

The fastest way to resolve this problem is to set the versions of both of the conflicting dependencies to any.

Hold on - I know what your thinking. We will NOT leave them as any.

pubspec.yaml
dependencies:
  # ...
  xml: any # <- don't leave me like this - read further!
  intl_translation: any # <- don't leave me like this either!

That loosens the version constraints from major versions (1.x.x - 2.x.x) to, you know, any version of the package that has ever existed.

This lets pub’s version constraint solver do its magic and figure out the compatible packages for you. After that change, refetch your dependencies by running flutter packages get. There’s a good chance that the following happens:

Resolving dependencies... 
Got dependencies!

We’re not done yet!

After getting the project to build, you should tighten the dependency versions back to use semantic versioning like they previously did. Open the generated pubspec.lock file and find the dependencies that were previously conflicting.

pubspec.lock
# Generated by pub
# See https://www.dartlang.org/tools/pub/glossary#lockfile
packages:
  xml:
    # ...
    version: "3.0.1" # the version of "xml" package that worked fine
                     # with "intl_translation".
  intl_translation:
    # ...
    version: "0.17.0" # the version of "intl_translation" package
                      # that worked fine with "xml".

From that lockfile, we can see that the xml package version 3.0.1 and intl_translation package version 0.17.0 play along together well. As the last step, replace any with the correct versions on your pubspec file:

pubspec.yaml
dependencies:
  # ...
  xml: ^3.0.1
  intl_translation: ^0.17.0

Refetch your dependencies one last time by running flutter packages get to verify that this does indeed work and then you’re good to go.

Remember: you should never leave your versions as any - that’s simply just asking for trouble. Find the compatible versions from pubspec.lock and use those ones. Having nondeterministic dependencies is a surefire way of breaking your app in hard to debug ways in the future. Just don’t do it.