Closed general

Stale caret ranges on fast-moving 0.x deps wedge the whole fleet update sweep - add publish-time range lint + dependent notification

Drew Owens · 3mo ago ·closed by Colby Knox

Two live incidents today, same root cause:

  1. adom/wiki-notify-gchat declared adom/adom-google ^0.7.0; adom-google moved to 0.8.x and adom-google-adom requires ^0.8.3. Result on every container with both: pkg update fails with 'cannot satisfy adom/adom-google@^0.8.3 and adom/adom-google@latest and adom/adom-google@^0.7.0 simultaneously'. (Fixed by hand in wiki-notify-gchat 1.6.5 after John caught it and filed an issue manually.)
  2. Independently, the same morning: 'cannot satisfy adom/molecule-publish@latest and adom/molecule-publish@^1.0.0 simultaneously (resolved to 2.0.0)' from a different dependent.

Structural causes: the registry resolves one flat, single-version constraint set across everything installed (CLIs on PATH can only exist once), so ONE stale range anywhere wedges the entire sweep; the org ships 0.x minors fast and caret semantics (^0.7 excludes 0.8) turn every dependent's range into a ticking clock; and the auto-update path adds @latest constraints that collide with conservative ranges.

Proposals (either or both):

  • Publish-time lint: when a package declares a dep range that excludes that dep's CURRENT latest, warn (or block without --skip-lint): 'your range ^0.7.0 excludes adom/[email protected]'. Cheap, catches the mistake at the moment it is made.
  • Dependent notification: when a publish leaves any dependent's published range behind, auto-notify those dependents (the wiki already has issues + email notifications - today that loop was a human noticing a broken sweep and filing by hand). The Dependents index needed to find them already exists.

Related, known separately: owner/slug-qualified pins break on page transfer/rename (the core 4.10/4.11 dangling-pin case) - same brittleness, different axis.

1 Reply

Colby Knox · 3mo ago

Client half fixed in adom-wiki-cli 1.0.56; server halves relayed to the wiki thread.

Publish-time range lint (your proposal 1), client side: pkg publish and pkg lint now check every owner-qualified dependency range against that dep's CURRENT latest. A range that excludes it warns:

STALE_RANGE: dependencies[adom/adom-google] = ^0.7.0 excludes its current latest 0.8.14
  -> widen or bump the range (e.g. ^0.8.14) before this publish becomes the fleet's problem

Verified live against the real incident range (^0.7.0 vs 0.8.14). Warning-level, best-effort by design: unknown range forms answer None (never a false positive), network failures skip silently, wildcards are exempt. Range math is new in core::semver (npm caret/tilde/exact/wildcard) with the caret-excludes-0.x-minor case pinned by tests, since that semantics is the whole wedge.

Still server-side, relayed: (a) the same lint enforced at the publish endpoint, so hand-rolled publishes cannot reintroduce it -- same defense-in-depth split as the component lint; (b) your proposal 2, dependent notification via the Dependents index + issues/email when a publish leaves a dependent's range behind. Both are on the wiki thread's ledger now.

The sweep-survival half (a conflict no longer stopping every other package's update) is #14, same release.

The transfer/rename dangling-pin axis you noted stays open as its own known issue -- range math does not touch it.

Log in to reply.