Repository navigation
Hosted yarn classic offline-mirror refusal misses a mirror set in a workspace member's .yarnrc, so installs run from that member fail the integrity check while the scan reports success and VEX attests #1115
Description
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
#1083 (fixing #1013 / #1078) resolves yarn-offline-mirror from the workspace root's .yarnrc / .npmrc, the user / global rc files, the root's ancestors and the env. It never reads a workspace member's .yarnrc. But yarn 1 builds its config registries from the directory it runs in (config.cwd, the member when you cd packages/a && yarn install or yarn --cwd packages/a install), not from the workspace root. The root still supplies the lockfile (lockfileFolder).
So when a member sets a mirror, a hosted scan from the root pins the root yarn.lock and reports success with no redirect_yarn_classic_offline_mirror. The in-run and standalone VEX attest not_affected. Every frozen install run from that member then takes the upstream left-pad-1.3.0.tgz from the member's mirror and fails Integrity check failed for "left-pad". This is the #1013 failure, reached through a config file the resolver doesn't look at.
Impact
- Install workflows that run per member (
cd packages/x && yarn install --frozen-lockfile,yarn --cwd packages/x install) break after a hosted scan that reported success. - VEX says
not_affectedwhile the member's install fails, and any install that does go through serves the unpatched mirror bytes. - Installs from the root are fine (the member rc isn't read there), so the breakage only shows up in member-dir workflows.
Repro (Linux, yarn 1.22.22, local mock patch API)
mkdir -p p/packages/a m && cd p
echo '{"name":"root","version":"1.0.0","private":true,"workspaces":["packages/*"]}' > package.json
echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > packages/a/package.json
echo "yarn-offline-mirror \"$PWD/../m\"" > packages/a/.yarnrc
(cd packages/a && yarn install) # yarn reads packages/a/.yarnrc; m/ gets left-pad-1.3.0.tgz
socket-patch scan --mode hosted --vex vex.json --json --yes # from the root
# exit 0, status success, warnings: [redirect_yarn_classic_berry_migration_risk] only
# yarn.lock left-pad -> hosted URL; vex.json: not_affected
rm -rf node_modules packages/a/node_modules
(cd packages/a && yarn install --frozen-lockfile)
# error ...: Integrity check failed for "left-pad" (computed integrity doesn't match our records, got "sha512-XI5MPzV…")Control: the same yarn-offline-mirror line in the root .yarnrc is refused with redirect_yarn_classic_offline_mirror and the lock is left untouched (pass).
Expected vs actual
- docs/ecosystems.md (yarn classic): "A project that sets
yarn-offline-mirroris refused withredirect_yarn_classic_offline_mirror. The mirror is resolved the way yarn 1 resolves it…" Yarn 1 resolves it from the directory the install runs in, and a workspace member is a supported install directory (the hosted member refusal from Hosted scan/get run from a yarn classic workspace member still reports success while pinning nothing: the #598 governing-root refusal covers pnpm and cargo only #884 / Fix hosted runs from npm/yarn/bun workspace members pinning nothing (#884) #901 is built on that). - Expected: when any declared workspace member's
.yarnrc/.npmrcsets a mirror that isn'tfalse, refuse withredirect_yarn_classic_offline_mirror, or at least warn and keep VEX from attesting. - Actual: the scan pins, reports success, VEX attests, and member-dir installs fail.
Matrix (main ea09714, ×2 per cell)
| OS | yarn | member cd install |
--cwd member install |
|---|---|---|---|
| Linux | 1.22.22 | fail (integrity) | fail (integrity) |
| Linux | 1.10.1 | fail (integrity) | not run |
| Linux | 1.7.0 | installs patched (no integrity line in 1.7 locks, as in #1013) |
not run |
macOS and Windows weren't run for this shape. The root-level / user / env / BOM cells of #1083 pass on a cross-OS probe from this run.
Suspect code
crates/socket-patch-cli/src/commands/scan/hosted.rs:996and:1825:resolve_outer_yarn_mirror_for_process(&common.cwd)only gets the scan root.crates/socket-patch-core/src/patch/redirect/yarnrc.rs:225(resolve_outer_yarn_mirror): layers are project, user, prefix, then the project's ancestors. Members (descendants listed inworkspaces) never count.crates/socket-patch-core/src/patch/redirect/mod.rs:3454(preflight_yarn_classic_hostedcall): only the root.yarnrc/.npmrctexts are passed in.
Related: #1013 / #1078 (closed by #1083), #691 (member-dir installs, vendored).
Activity
mikolalysenko commentedon Oct 8, 2026
[agent] Triaged: priority:p1 (yarn classic). Not a duplicate: #1013 / #1078 (closed by #1083) cover the root, user, ancestor and env mirror layers. This report is about the workspace-member
.yarnrclayer, whichresolve_outer_yarn_mirrornever reads. No open PR covers it yet.Generated by Claude Code
mikolalysenko commentedon Oct 8, 2026
[agent] Another trigger for the same gap, on main
e2d9633(yarn 1.22.22, Linux, ×2): the mirror can also be set in the member's.npmrc(yarn-offline-mirror=./mirrorinpackages/m/.npmrc). yarn 1 reads it the same way when installing from the member.yarn installfrompackages/m. It fillspackages/m/mirror/left-pad-1.3.0.tgz.socket-patch scan --mode hostedfrom the root. It exits 0, pinsleft-pad, and gives no mirror warning.node_modules, thencd packages/m && yarn install --frozen-lockfile. It fails withIntegrity check failed for "left-pad"and nothing is installed.The
.yarnrccontrol reproduces the same way on this commit. So a fix for the member-level resolver should read both rc files on the member's directory chain.Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
[agent] Yarn-classic bug-hunt run 34, main
03b9418, yarn 1.22.22, reproduced ×2. This also hits the staged vendored→hosted takeover (#1039). With a project-root.yarnrcmirror, the takeover is retracted (redirect_yarn_classic_offline_mirror+redirect_takeover_kept_vendored). With the same mirror inpackages/a/.yarnrc, it isn't:So the takeover removes a vendored setup and leaves a hosted pin that member-dir installs can't satisfy. Member-dir installs already failed under the vendored setup, because of #691 (the
file:./.socket/…path resolves against the member, and with a mirror yarn falls back to the mirror's same-named upstream tarball). Root installs pass in both modes. The fix for this issue (reading member rc files in the mirror check) should also feed the takeover retract.Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
v5 triage: P2, not a release blocker. Retain a workspace-member-only Yarn offline mirror at P2. The primary registry/cache install behavior has separate blockers.
This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.