GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Vendored yarn berry revert restores the pre-vendor lock entry verbatim, so after upgrading from yarn 4.0.x it writes back a bare-hex checksum and every `yarn install --immutable` fails YN0028 · Issue #759 · SocketDev/socket-patch Closed Labels agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:yarn-berryYarn Berry (2+)Yarn Berry (2+)priority:p2 Description[agent] Found by the scheduled Yarn Berry (2+) bug-hunt routine (ledger #305). Summary
The revert exits 0 and reports The hosted twin is fine. Hosted rollback rebuilds the entry and calls ImpactA team that vendored under yarn 4.0.x and later upgraded yarn can't cleanly unvendor: ReproHarness: yarn bundles from npm mkdir app && cd app echo '{"name":"up","dependencies":{"left-pad":"^1.3.0","is-number":"^7.0.0"}}' > package.json echo 'nodeLinker: node-modules' > .yarnrc.yml [email protected] install # lock: version 8, bare-hex checksums socket-patch scan --mode vendored --yes --api-url $MOCK --org org --api-token x [email protected] install # yarn upgrade: lock version 10, every checksum respelled 10c0/<hex> socket-patch rollback --api-url $MOCK --org org --api-token x # or: socket-patch vendor --revert grep -A3 '"left-pad@' yarn.lock # checksum: 3fb59c76… (bare) among 10c0/ entries mkdir f && cp package.json yarn.lock .yarnrc.yml f/ && cd f [email protected] install --immutable # exit 1, YN0028 on the left-pad checksum line Expected vs actual
Matrix (Linux, node 22, main
|
| vendored with | yarn after upgrade | revert command | fresh --immutable |
|---|---|---|---|
| 4.0.2 | 4.12.0 | vendor --revert |
fail YN0028 |
| 4.0.2 | 4.12.0 | rollback |
fail YN0028 |
| 4.0.2 | 4.18.1 | vendor --revert |
fail YN0028 |
| 4.0.2 | 4.18.1 | rollback (twice, separate projects) |
fail YN0028 |
| 4.0.2 | (none) | rollback |
pass (byte-exact, covered in earlier runs) |
| 4.0.2 (hosted) | 4.18.1 | rollback |
pass (writes 10c0/) |
Release 4.0.0 (npm) behaves the same (vendor --revert, then 4.18.1 --immutable fails), so this isn't a regression. Release 3.3.0 doesn't vendor this setup. macOS and Windows weren't probed (the routine can't currently push probe branches), but the code path doesn't depend on the OS.
crates/socket-patch-core/src/vendor/yarn_classic_lock.rs:646: replace_block(text, block, &original, …) writes the recorded original lines verbatim.crates/socket-patch-core/src/vendor/yarn_berry_lock.rs:755: the berry revert calls that shared helper with no re-spelling of checksum:. One possible fix is to pass the restored berry block's checksum: through checksum_in_lock_spelling(<live lock>, …) before writing it.Priority: P1 → P2. After a Yarn version upgrade the lock checksum spelling causes a visible failure; this is recoverable compatibility work.
[agent] Yarn Berry bug-hunt run 29 (ledger #305) found a second symptom of the same verbatim restore, with no yarn upgrade involved. Main 05ecc6e, yarn 4.0.2 and 4.18.1, Linux, node-modules linker.
If a new descriptor of the patched package is added after vendoring, the revert drops it. Example: a workspace member adds "lpx": "1.0.0" while the root has ^1.0.0. The name-keyed resolutions pin covers the new descriptor and installs patched bytes (correct), so the vendored lock has one file: entry. vendor --revert and rollback then write back the pre-vendor "lpx@npm:^1.0.0": block alone. Both exit 0, and every fresh yarn install --immutable fails YN0028:
➤ YN0028: │ +"lpx@npm:1.0.0, lpx@npm:^1.0.0":
➤ YN0028: │ -"lpx@npm:^1.0.0":
| yarn | vendor --revert |
rollback |
|---|---|---|
| 4.0.2 | exit 0, fresh --immutable YN0028 |
exit 0, YN0028 |
| 4.18.1 | exit 0, YN0028 | exit 0, YN0028 |
Repro:
mkdir -p p/packages/b && cd p echo '{"name":"root","version":"1.0.0","private":true,"workspaces":["packages/*"],"dependencies":{"lpx":"^1.0.0"}}' > package.json printf 'nodeLinker: node-modules\n' > .yarnrc.yml && yarn install socket-patch scan --mode vendored --yes echo '{"name":"b","version":"1.0.0","dependencies":{"lpx":"1.0.0"}}' > packages/b/package.json && yarn install socket-patch vendor --revert # exit 0 # fresh checkout: yarn install --immutable → YN0028
The restored entry key should be rebuilt from the lock's current descriptors for the package, not taken from the snapshot. That would also fix the checksum spelling this issue reports. The hosted pin has a related problem when a descriptor is added after pinning (re-scan dead end, and a rollback that writes duplicate blocks); that is filed as #1082.
Generated by Claude Code
[agent] Re-checked on main 1779317 (yarn 4.0.2 and 4.18.1, Linux). Both symptoms still fail:
vendor --revert: the bare-hex checksum: is written back, and every fresh --immutable fails YN0028."left-pad": "1.3.0" beside the root's ^1.3.0 after vendoring, then vendor --revert or rollback: exit 0, the pre-vendor "left-pad@npm:^1.3.0": block comes back alone, and YN0028 follows (plain and hardened).#1397 (#1082) fixed the hosted side of the second symptom and the vendored alias variant (lp: npm:[email protected] added after vendoring, then revert: now passes). The vendored plain-member variant still goes through the verbatim restore.
Generated by Claude Code
[agent] Yarn Berry bug-hunt run 39 (ledger #305) found a third symptom of the same verbatim restore: the vendored twin of #1435, which #1436 fixed only for hosted pins. Main 15c2c83, yarn 4.0.2 and 4.18.1, Linux, node-modules linker.
If a workspace member removes its descriptor of the vendored package after vendoring (another member keeps it), vendor --revert, rollback and remove left-pad all write back the pre-vendor merged block, including the removed member's descriptor. All three exit 0, and every fresh yarn install --immutable fails YN0028:
➤ YN0028: │ -"left-pad@npm:1.3.0, left-pad@npm:^1.3.0":
➤ YN0028: │ +"left-pad@npm:1.3.0":
➤ YN0028: │ The lockfile would have been modified by this install, which is explicitly forbidden.
The vendored state itself was fine: the fresh --immutable install right after yarn remove passed.
| yarn | vendor --revert |
rollback |
remove left-pad |
|---|---|---|---|
| 4.0.2 | exit 0, YN0028 | exit 0, YN0028 | exit 0, YN0028 |
| 4.18.1 | exit 0, YN0028 | exit 0, YN0028 | exit 0, YN0028 |
Repro:
mkdir -p p/packages/a p/packages/b && cd p echo '{"name":"root","private":true,"workspaces":["packages/*"]}' > package.json echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"^1.3.0"}}' > packages/a/package.json echo '{"name":"b","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > packages/b/package.json printf 'nodeLinker: node-modules\n' > .yarnrc.yml && yarn install socket-patch get <uuid> --mode vendored --yes # or scan --mode vendored (cd packages/a && yarn remove left-pad) # b still uses [email protected] socket-patch vendor --revert --yes # or rollback / remove left-pad # fresh checkout: yarn install --immutable -> YN0028 (the removed "left-pad@npm:^1.3.0" key is back)
For a fix, the restore should key the entry by the descriptors that live lock entries still use, as #1436 now does for hosted (restore_berry), and not by the block recorded at vendor time.
Generated by Claude Code
[agent] Claiming this issue (shared root cause: the vendored yarn berry revert writes back the lock block recorded at vendor time verbatim instead of re-deriving its key and checksum spelling from the live lock). Branch: agent/fix-berry-vendored-verbatim-restore. Claim-ID: 2026-10-13T03:21:07Z-ce3a89
Generated by Claude Code