Skip to content

[dsh bundle] boot crash window: stale pnpm metadata installs 0.1.117 copy while global 0.1.120 declares the bundle #953

Closed

Description

@ranxianglei

Boot crash window after 0.1.120 release: stale pnpm metadata installs a 0.1.117 profile copy while dsh bundles detection hits the global 0.1.120.

Repro (real, hit on two machines)

  1. Machine has a global billion-context >= 0.1.120 (npm i -g)
  2. pnpm registry-metadata cache is still fresh from before the release
  3. dsh plugin --profile <name> add billion-context → pnpm resolves ^0.1.117 from cache (output shows resolved 1, reused 1, downloaded 0) → profile copy = 0.1.117 (no exports["./dsh"])
  4. dsh exportsPatch detects the bundle via resolveBundleDir which is installation-anchor-first → hits the GLOBAL 0.1.120 (has the dsh.bundle declaration) → profile joins dsh.profile.bundles
  5. dsh web → cordis loader imports billion-context/dsh from the profile dir → 0.1.117 has no such export → ERR_MODULE_NOT_FOUND → plugin tree fails to load, dsh will not boot

Impact

  • Pure dsh users (no global bili): detection hits the profile copy (no declaration) → plain-dependency warning, NO crash — self-heals on cache expiry / re-add
  • Machines with global >=0.1.120 + stale cache + add inside the window: hard boot crash, stable across remove/add (same cached resolution)
  • Window closes as pnpm caches expire; new installs resolve 0.1.120+ which carries the export. Only machines that added during the window keep a 0.1.117 copy until they update.

Fix / workaround

  • Immediate: dsh plugin --profile <name> add billion-context@0.1.120 (pin) or @latest once caches refresh — verified, boots fine
  • Nothing we can ship in-package: the mismatch is dsh-side (detection resolves installation-first, loading resolves profile-first). A future bundled-yml change cannot rescue old copies that lack the subpath export.
  • Doc note already in PR feat: dsh-side install channel — zero bili commands for dsh users (#949) #950 READMEs ("Requires a published release that carries dsh.bundle.patch.yml"); could add "pin @latest if dsh fails to boot after add". Closing as windowed/obsolete once caches age out — keep as the canonical record.

Found while verifying the 0.1.120 release (#949 / PR #950).

Activity

  1. ranxianglei commented on Sep 18, 2026

    @ranxianglei
    OwnerAuthor

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 On it — auditing #953 before touching anything:

    1. Verifying the package-side claims against the npm registry (exports diff between 0.1.117 and 0.1.120, publish timestamps).
    2. Re-checking the layering — symptom vs root cause, and whether anything shippable in-package could narrow the window.
    3. Adding the suggested pin-workaround note to the dsh-lane docs (en + zh), as a small PR referencing this issue (no auto-close — keeping this open as the canonical record until the window ages out).

    Full findings + PR link in a follow-up comment shortly.

  2. ranxianglei commented on Sep 18, 2026

    @ranxianglei
    OwnerAuthor

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 Audit complete. Findings below, then the deliverable.

    Verification (what I checked, with evidence)

    • Package side — confirmed. npm view billion-context@0.1.117 exports returns nothing (0.1.117 has no exports field at all), while 0.1.120 carries exports["./dsh"] → ./dist/agent/dsh-native.js plus the bundled dsh.bundle.patch.yml (manifest declaration verified in published 0.1.120, shipped by PR feat: dsh-side install channel — zero bili commands for dsh users (#949) #950 / commit 8eca91f). So a profile copy of 0.1.117 cannot satisfy import 'billion-context/dsh' — the ERR_MODULE_NOT_FOUND mechanism is real, not a misread.
    • Window timing — consistent. 0.1.120 published 2026-09-18 14:11 UTC; ~6h old at time of this analysis. Machines whose pnpm registry-metadata cache predates that (and can't revalidate) are still inside the window. "Windowed/obsolete once caches age out" holds.
    • dsh-side asymmetry (detection installation-anchor-first via resolveBundleDir vs loading profile-first) — not verifiable from this repo (it's dsh's code), but it's fully consistent with your two-machine repro and the exact failure signature, so I accept it as reported rather than re-litigating.

    Layering judgment

    • Symptom: hard boot crash after add. Root cause: version skew between two different resolution anchors — bundle detection reads the global install (new, declares the bundle) while cordis loading imports from the profile dir (stale-cache-resolved, lacks the subpath export) — triggered only inside the post-release stale-metadata window. Your analysis already landed on exactly this.
    • "Nothing we can ship in-package" — agreed. An already-installed 0.1.117 profile copy physically lacks exports["./dsh"]; no future release or yml change can rewrite what's in someone's profile node_modules. The fix surface is (a) the pin workaround you listed, (b) dsh-side hardening.
    • One observation for the record (no action taken, dsh-project territory): if dsh ever validates the version it resolves during add against a minimum declared in the bundle manifest (e.g. the "dsh" key in package.json), in-window adds would fail fast with a clear error instead of silently mounting a non-matching copy and crashing at boot. Leaving it here for your judgment — I'm deliberately not filing it separately.

    Deliverable — doc note shipped

    Per your suggestion, the pin workaround is now in the dsh-lane docs (both READMEs, right next to the existing "Requires a published release that carries dsh.bundle.patch.yml" note):

    If dsh fails to boot right after an add with ERR_MODULE_NOT_FOUND on billion-context/dsh, the profile resolved a pre-bundle copy from a stale package-metadata cache (#953) — re-add pinned: dsh plugin --profile <name> add billion-context@latest.

    PR: #954 (docs-only; Part of #953, intentionally not auto-closing — keeping this issue open as the canonical record until the window ages out). Pre-flight on current master + commit: typecheck clean, tests 1881 pass / 0 fail / 2 skip, build success.

    Conclusion

    Bug confirmed real but strictly windowed; self-heals as caches age; no code change warranted in this repo. Recommend: keep #953 open as the record, merge PR #954 for the user-facing note, close #953 when you judge the cache window dead.

    中文摘要:已核实 0.1.117 确实没有 exports["./dsh"](0.1.120 才有),崩溃机制与时间窗判断成立;根因是 dsh 侧"检测走全局锚点、加载走 profile 锚点"的版本错位,包内无可修复项——已在两个 README 的 dsh 安装段落补上 @latest 固定重装提示(PR #954),本 issue 建议保留为正式记录、待缓存窗口过期后关闭。

  3. added 4 commits that reference this issue on Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions