You published `colour_tools` 2.3.0 to pub.dev yesterday, but it declares `collection: ^1.15.0` while calling an API added in a later 1.x; with Dart's pub, do you retract, publish a fix, or discontinue?
answer
- retraction is not deletion
- seven days from publication
- a lax constraint cannot be fixed forward
- the lockfile keeps a retracted version
- discontinued: badge, gone from search
basics
~20 sPublish 2.3.1 with a corrected lower bound and retract 2.3.0 while inside its seven-day window: a fix alone leaves the solver free to pick 2.3.0 wherever 2.3.1 doesn't fit. Discontinuing is for abandoned packages, not one bad version.
solid answer
~40 sThis is the case retraction exists for. From the package's Admin tab on pub.dev you can retract a version within seven days of publication, and restore it within seven days of retraction. The version stays listed under **Retracted versions** with a RETRACTED badge, but the solver stops choosing it for new resolutions. Publishing 2.3.1 with `collection: ^1.18.0` helps users who can take it, yet pub will still pick 2.3.0 for anyone whose other constraints hold `collection` below that bound - a lax constraint can't be fixed forward. For an ordinary bug, don't retract: publish a fix and describe it in `CHANGELOG.md`, which disrupts users less. Projects that already have 2.3.0 in `pubspec.lock` keep it. Discontinuing marks the whole package unmaintained - a DISCONTINUED badge, no search listing - which is the wrong tool here.
code
yaml · 11 linesname: colour_tools
version: 2.3.1
description: Colour conversion and contrast helpers for Dart and Flutter.
environment:
sdk: ^3.13.0
dependencies:
# 2.3.0 declared ^1.15.0 but used an API from a later 1.x release
# (2.3.0 is retracted). The bound now matches the API actually used.
collection: ^1.18.0go deeper
Recall that pub.dev versions can't normally be deleted, and that retracting one version differs from discontinuing a whole package.
Explain the seven-day retraction window, the RETRACTED badge, and why a lockfile that already holds the version keeps using it.
Show why a lax constraint can't be fixed forward - the solver still reaches the bad version - and choose retraction plus a fix, reserving retraction for constraint errors.
Turn it into release policy: constraint checks before publishing, a named owner who can act inside the seven-day window, and a rule for when to discontinue.
## Background: published versions stay published pub.dev is the public registry for Dart and Flutter packages. Its policy **disallows unpublishing** except in very few cases, because other packages may already depend on any version you upload. So when a release is wrong, the question is never "how do I delete it?" but which of three tools to use: | Tool | Scope | Time limit | What users see | Reversible | |---|---|---|---|---| | **Publish a new version** | one new version | none | a newer version to upgrade to | n/a | | **Retract a version** | one version | within 7 days of publication | the version under *Retracted versions*, with a RETRACTED badge; the solver avoids it | restore within 7 days of retraction | | **Discontinue the package** | the whole package | none | a DISCONTINUED badge, no search listing, an optional suggested replacement | yes, any time | ## Why fixing forward fails for a bad constraint The scenario: `colour_tools` 2.3.0 declares `collection: ^1.15.0`, but its code calls an API that only exists in a later 1.x release of `collection`. The constraint is **lax**: it admits versions the code cannot compile against. Walk through what the version solver does for a user of the package: 1. The user's app also depends on some package that holds `collection` at an older 1.x, below the release with the needed API. 2. The solver looks for the newest `colour_tools` that fits. You have published 2.3.1 declaring the correct, higher lower bound, but 2.3.1 conflicts with the user's other constraint. 3. 2.3.0 *does* fit on paper, because it claims `^1.15.0`. The solver picks it. 4. The build fails in `colour_tools` code the user never touched. Publishing a newer version changes nothing for that user - dart.dev states exactly this: a newer version won't stop the solver from picking the old one, which may be the only version it can choose. **Retracting 2.3.0** removes it from new resolutions, so the user either resolves to an older, correctly constrained 2.2.x, upgrades the other dependency, or gets an explicit dependency conflict - all better than a broken build. ## What retraction does and does not do - It is **not deletion**. The version remains on pub.dev and downloadable; its detail page shows RETRACTED. - It affects **new resolutions**. A project whose `pubspec.lock` already contains 2.3.0 keeps using it until it upgrades. - A consumer who truly needs a retracted version can pin it exactly under `dependency_overrides` in the root `pubspec.yaml`. - Consumers move off it with `dart pub upgrade colour_tools` if a newer version fits, or by downgrading to the newest non-retracted version. - It is only available **within seven days of publication**; after that you can only fix forward. - Retraction arrived in Dart 2.15; older SDKs' solvers ignore the retracted status. - Only an uploader, or an admin of the owning verified publisher, can retract or restore, from the package's **Admin** tab. For an **ordinary bug** - a wrong conversion constant, a crash in one function - retraction is overkill. Publish 2.3.1 with the fix and explain it in `CHANGELOG.md`; users upgrade normally, and nobody's resolution is disturbed. ## Discontinuing: a package-level signal Discontinuing is for when you stop maintaining the package altogether - for example, when `colour_tools` is superseded by a new package. On the Admin tab you mark it **discontinued** and may name a **suggested replacement**. The package: - remains published and viewable on pub.dev, - shows a clear DISCONTINUED badge, - no longer appears in pub.dev search results, - is flagged to dependents by `dart pub outdated`. The mark can be removed later. It says nothing about any single version, so it would not help the users stuck on 2.3.0. ## Decision rules 1. Wrong or missing **dependency constraint**, discovered within seven days: publish the corrected version **and** retract the bad one. 2. Ordinary **bug**: publish a fix and document it in the changelog; don't retract. 3. Past the **seven-day window**: fix forward and tell affected users how to adjust their other constraints. 4. **Abandoning** the package: discontinue it and name a replacement.
- A consumer genuinely needs retracted 2.3.0. Can they still use it?Yes. If 2.3.0 is already in their `pubspec.lock`, pub keeps using it. To select it in a fresh resolution they must pin it exactly under `dependency_overrides` in their root `pubspec.yaml`, since ordinary constraints no longer resolve to a retracted version. It's an escape hatch, not a long-term plan.
- The seven-day window has passed. What are your options?Retraction is no longer offered, so fix forward: publish 2.3.1 with the corrected bound, explain the problem and the workaround in `CHANGELOG.md`, and tell affected users which constraint to raise. Unpublishing is disallowed except in very few cases, so plan for 2.3.0 to stay resolvable.
- When is discontinuing the right call, and what do users see?When you stop maintaining the package, for example because a successor replaces it. On the Admin tab you mark it discontinued and can name a suggested replacement. It stays published and viewable with a DISCONTINUED badge, drops out of search results, and `dart pub outdated` flags it to dependents. You can remove the mark later.
saying these in an interview costs you the question
- Retracting a version deletes it from pub.dev and from users' caches
- Publishing 2.3.1 always stops the solver from choosing the broken 2.3.0
- A version can be retracted at any time after it is published
- Discontinuing a package removes it so nobody can depend on it anymore
- Every version with an ordinary bug should be retracted