You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
After yarn remove of a hosted-pinned yarn berry package, its leftover resolutions pin makes rollback, remove and list fail forever with hosted_wiring_contested, and the remedy they print (re-run the hosted scan) changes nothing #1203
[agent] Found by the scheduled Yarn Berry (2+) bug-hunt routine (ledger #305).
Summary
Since #465, a hosted yarn berry pin lives in two places: a root package.jsonresolutions entry ("left-pad@npm:1.3.0": "<hosted url>") and a lock entry keyed left-pad@<hosted url>. A routine yarn remove left-pad deletes the dependency and the lock entry, but yarn never touches resolutions, so the Socket selector stays in package.json and now matches nothing.
Lockfile discovery reads that leftover selector as Socket hosted wiring that no lock entry attributes, so HostedInventory marks it contested. From then on:
command
result
exit
rollback (1st)
restores the other hosted packages, then partial_failure
1
rollback (every later run)
hosted_wiring_contested
1
list
hosted_wiring_contested error, lists nothing (also for the still-pinned packages)
1
remove <uuid> / remove pkg:npm/left-pad@1.3.0
not_found
1
scan --mode hosted (the printed remedy)
success, but the left-pad selector is untouched; it only re-pins the packages rollback just restored
0
scan --mode hosted --prune
success, no change
0
The refusal says "reconcile the lockfiles (re-run socket-patch scan --mode hosted) or restore them from version control (git checkout -- package.json)". The first remedy is a no-op, as the table shows (rollback → scan → rollback just loops). The second one undoes the user's yarn remove. The only way out is deleting the resolutions key by hand. After that, list and rollback work again.
This is the hosted counterpart of the vendored "dependency removed" class fixed in #689 (#665) and #1147 (#1132/#1140/#1142). Vendored berry handles the same flow correctly on this main: vendor --check names it, and scan --mode vendored --prune / vendor --revert / rollback / remove retire the stale resolutions entry and tarball.
Impact
socket-patch rollback exits 1 permanently in any hosted yarn berry project after a patched dependency is uninstalled. That breaks CI or uninstall scripts that run it.
socket-patch list fails for the whole project, hiding the pins that are still live.
A dead Socket URL stays in package.json forever, and no command removes it.
Repro (yarn 4.18.1 or 4.0.2, node-modules linker; local mock of the patch API serving left-pad@1.3.0 and ms@2.1.3 hosted patches with yarn-berry-zip checksums, plus /upstream/npm/<uuid>.json)
Expected: a hosted selector whose package no lockfile resolves any more is leftover wiring that socket-patch wrote itself, so there's nothing left to attribute. rollback / remove (and scan --mode hosted --prune) should drop it with a warning, as the vendored revert does with vendor_lock_entry_removed (Fix vendored revert reading a removed dependency as drift (#1132, #1140, #1142) #1147). CLI_CONTRACT's hosted_wiring_contested row says the remedy is to "fix or git checkout the named lockfile", and the refusal tells the user to re-run the hosted scan. Neither works here: re-scanning doesn't touch the selector, and git checkout -- package.json reverts the user's own change. Failing a fix, the printed remedy at least has to work.
Actual:rollback, remove and list exit 1 forever, and the remedy loops.
Matrix (Linux, main 03b9418, Node 22)
yarn
rollback after yarn remove
list
remedy scan clears it
release 4.0.0
4.0.2
exit 1 (x2)
exit 1
no
n/a (lock-only pin)
4.18.1
exit 1 (x2, three separate projects)
exit 1
no
list passes, nothing left behind
yarn install --immutable passes in every cell, and VEX (vex --product …) still verifies the remaining pinned package. The decision is made on file text, so it isn't OS-specific and needs no probe run.
Suspect code
crates/socket-patch-core/src/patch/redirect/upstream/mod.rs:216: the discovery.recognized loop marks the package.json reference as contested because no pin (lock entry) carries its uuid. It doesn't distinguish "no lock entry resolves this package any more" from "the lockfiles disagree".
crates/socket-patch-core/src/patch/redirect/upstream/npm.rs:653 and :777: the berry hosted restore walks lock pins and removes their resolutions selectors. A selector whose lock entry is gone is never a pin, so nothing retires it.
The refusals are at crates/socket-patch-cli/src/commands/rollback.rs:907 / :1347, remove.rs:367 and list.rs:398.
[agent] Same dead end after an upgrade to a version with no patch, instead of a removal (yarn 4.18.1, main 03b9418). yarn up left-pad@1.2.0 after the hosted pin leaves resolutions["left-pad@npm:1.3.0"] behind, with left-pad@npm:1.2.0 in the lock. The first rollback gives partial_failure (exit 1) and the second hosted_wiring_contested. The remedy scan --mode hosted re-pins only ms, and the next rollback is partial_failure again, with the 1.3.0 selector still there. A fix should cover any change that leaves no lock entry for the pinned name@version, not only yarn remove.
v5 release blocker (P1). A normal yarn remove must not strand Socket resolutions and make list/rollback unusable with an ineffective rescan remedy.
This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.
[agent] Claiming for v5 blocker burn-down (shared root cause: berry hosted resolutions selector left after yarn remove is treated as contested). Branch: agent/v5-berry-leftover-resolutions. Claim-ID: 2026-10-09T16:42:22Z-86d5f3
[agent] Found by the scheduled Yarn Berry (2+) bug-hunt routine (ledger #305).
Summary
Since #465, a hosted yarn berry pin lives in two places: a root
package.jsonresolutionsentry ("left-pad@npm:1.3.0": "<hosted url>") and a lock entry keyedleft-pad@<hosted url>. A routineyarn remove left-paddeletes the dependency and the lock entry, but yarn never touchesresolutions, so the Socket selector stays inpackage.jsonand now matches nothing.Lockfile discovery reads that leftover selector as Socket hosted wiring that no lock entry attributes, so
HostedInventorymarks it contested. From then on:rollback(1st)partial_failurerollback(every later run)hosted_wiring_contestedlisthosted_wiring_contestederror, lists nothing (also for the still-pinned packages)remove <uuid>/remove pkg:npm/left-pad@1.3.0not_foundscan --mode hosted(the printed remedy)scan --mode hosted --pruneThe refusal says "reconcile the lockfiles (re-run
socket-patch scan --mode hosted) or restore them from version control (git checkout -- package.json)". The first remedy is a no-op, as the table shows (rollback → scan → rollback just loops). The second one undoes the user'syarn remove. The only way out is deleting theresolutionskey by hand. After that,listandrollbackwork again.This is the hosted counterpart of the vendored "dependency removed" class fixed in #689 (#665) and #1147 (#1132/#1140/#1142). Vendored berry handles the same flow correctly on this main:
vendor --checknames it, andscan --mode vendored --prune/vendor --revert/rollback/removeretire the staleresolutionsentry and tarball.Impact
socket-patch rollbackexits 1 permanently in any hosted yarn berry project after a patched dependency is uninstalled. That breaks CI or uninstall scripts that run it.socket-patch listfails for the whole project, hiding the pins that are still live.package.jsonforever, and no command removes it.yarn removeleft nothing behind andlistsucceeds. This came in with theresolutionspin (Fix yarn berry hosted pin leaking npm auth (#404) #465).Repro (yarn 4.18.1 or 4.0.2, node-modules linker; local mock of the patch API serving left-pad@1.3.0 and ms@2.1.3 hosted patches with
yarn-berry-zipchecksums, plus/upstream/npm/<uuid>.json)Expected vs actual
rollback/remove(andscan --mode hosted --prune) should drop it with a warning, as the vendored revert does withvendor_lock_entry_removed(Fix vendored revert reading a removed dependency as drift (#1132, #1140, #1142) #1147). CLI_CONTRACT'shosted_wiring_contestedrow says the remedy is to "fix orgit checkoutthe named lockfile", and the refusal tells the user to re-run the hosted scan. Neither works here: re-scanning doesn't touch the selector, andgit checkout -- package.jsonreverts the user's own change. Failing a fix, the printed remedy at least has to work.rollback,removeandlistexit 1 forever, and the remedy loops.Matrix (Linux, main
03b9418, Node 22)yarn removelistlistpasses, nothing left behindyarn install --immutablepasses in every cell, and VEX (vex --product …) still verifies the remaining pinned package. The decision is made on file text, so it isn't OS-specific and needs no probe run.Suspect code
crates/socket-patch-core/src/patch/redirect/upstream/mod.rs:216: thediscovery.recognizedloop marks thepackage.jsonreference as contested because no pin (lock entry) carries its uuid. It doesn't distinguish "no lock entry resolves this package any more" from "the lockfiles disagree".crates/socket-patch-core/src/patch/redirect/upstream/npm.rs:653and:777: the berry hosted restore walks lock pins and removes theirresolutionsselectors. A selector whose lock entry is gone is never a pin, so nothing retires it.crates/socket-patch-cli/src/commands/rollback.rs:907/:1347,remove.rs:367andlist.rs:398.