Skip to content

Hosted scan on a Rush repo with subspaces never emits redirect_rush_repo_state_stale, so rush install fails on the shrinkwrap hash check with no warning #714

Description

[agent] Found by the scheduled pnpm bug-hunt routine (ledger #303).

Summary

With Rush subspaces enabled, the pnpm locks and the repo-state files that carry pnpmShrinkwrapHash both live per subspace, at common/config/subspaces/<name>/{pnpm-lock.yaml,repo-state.json}. scan --mode hosted correctly rewrites the subspace locks (docs: "subspaces included"). But the redirect_rush_repo_state_stale warning only checks for common/config/rush/repo-state.json (RUSH_REPO_STATE_REL), which doesn't exist in a subspace repo. So the warning never fires. With preventManualShrinkwrapChanges: true, the next rush install fails with "The shrinkwrap file hash does not match the expected hash", and the scan output gave no hint.

The non-subspace layout with the same setting emits the warning (control below). The documented recovery works in the subspace layout too: after rush update the hosted pins survive, and rush install installs the patched bytes. Only the warning is missing.

Impact

Low/medium. Nothing is mis-patched and nothing silently reverts. But in a Rush monorepo that uses subspaces and the (commonly enabled) preventManualShrinkwrapChanges, the hosted rewrite breaks CI's rush install, and the one warning meant to explain why is missing.

Repro (Linux, Node 22, Rush 5.180.0, local patch-API mock serving left-pad@1.3.0 / is-number@7.0.0 patches)

rush init
# rush.json: pnpmVersion 10.34.5; projects app (default subspace) -> left-pad@1.3.0, tool (subspaceName "tools") -> is-number@7.0.0
# subspaces.json: subspacesEnabled true, subspaceNames ["default","tools"]; mkdir common/config/subspaces/{default,tools}; rm common/config/rush/.pnpmfile.cjs
# pnpm-config.json: "preventManualShrinkwrapChanges": true
rush update && git add -A && git commit -qm init
socket-patch scan --mode hosted $API --json
#   status success, redirected 2, rewrittenFiles [common/config/subspaces/default/pnpm-lock.yaml, common/config/subspaces/tools/pnpm-lock.yaml]
#   warnings: ['redirect_pnpm_trust_lockfile']        <- no redirect_rush_repo_state_stale
git commit -qam pin && git clone -q . ../fresh && cd ../fresh && rush install
#   "The shrinkwrap file hash does not match the expected hash. Please run "rush update" ..." (exit 1)

Expected vs actual

  • Expected (docs/ecosystems.md, "npm: Rush monorepos"): editing a Rush lock outside rush update desyncs pnpmShrinkwrapHash, and "a redirect_rush_repo_state_stale warning flags this". The engine comment at crates/socket-patch-core/src/hosted/engine.rs:922-928 says to warn "when the rewrite actually landed in a Rush lock and the repo-state file that carries the hash is present". In a subspace repo that file is common/config/subspaces/<name>/repo-state.json, and it is present.
  • Actual: no warning. The scan reports a clean success.

Matrix (Linux, main 045d7ec, each run twice from scratch)

Layout pnpm redirect_rush_repo_state_stale rush install (clean clone)
subspaces (default + tools) 9.15.9 missing fails: shrinkwrap hash mismatch
subspaces (default + tools) 10.34.5 missing fails: shrinkwrap hash mismatch
no subspaces (control) 10.34.5 emitted (expected failure, warned)
subspaces, after rush update 10.34.5 n/a pass, both packages patched

macOS / Windows not tested (path logic only).

Suspect code

  • crates/socket-patch-core/src/hosted/engine.rs:761-769: rush_repo_state_present checks only RUSH_REPO_STATE_REL (common/config/rush/repo-state.json). It should also check the repo-state.json next to each rewritten subspace lock (common/config/subspaces/<name>/repo-state.json).
  • crates/socket-patch-core/src/hosted/engine.rs:930-944: the warning gate.

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions