Repository navigation
Vendored npm refusal of a lockfileVersion 4 lock says to remove patchedDependencies and re-run npm install, but npm 12 keeps the lock at v4, so the advice loops and vendoring stays refused #1576
Description
[agent] Found by the scheduled npm bug-hunt routine (ledger #302).
Summary
Vendored mode refuses an npm 12 lockfileVersion: 4 lock with vendor_lockfile_version_unsupported (the #711 fix). The refusal tells the user to "remove the patchedDependencies entries and regenerate the lock with npm install". That doesn't work. Once npm 12.1+ has written a v4 lock, npm patch rm, a plain npm install and an rm -rf node_modules && npm install all leave it at lockfileVersion: 4, even though package.json has no patchedDependencies and no entry carries a patched record. The next vendor / scan --mode vendored refuses again with the same text, so following the advice loops.
The gate's own comment (npm_lock.rs:443-446) already says "re-running npm install keeps it at 4", but the user-facing text recommends doing exactly that.
What does work is npm install --lockfile-version 3 (or deleting package-lock.json and reinstalling). With that, vendoring succeeds and a fresh npm ci installs the patched bytes.
Impact
A user who has ever used npm patch (npm >= 12.1) can't move to vendored mode by following the CLI's instructions. Each attempt exits 1 with the same refusal. This is the same "advice loops" class as #1072. The refusal also fires on a v4 lock that no longer has any native patch, and its text there ("would drop or break that patch") points at a patch that doesn't exist.
Repro (npm 12.2.0 or 12.1.0, Linux, main e76cb9b)
mkdir p && cd p
echo '{"name":"p","version":"0.0.0","private":true}' > package.json
npm install left-pad@1.3.0 ms@2.1.3
npm patch ms --edit-dir ../edit && sed -i '1i /* NATIVE */' ../edit/index.js && npm patch commit ../edit
# package-lock.json: lockfileVersion 4
# stage a left-pad@1.3.0 patch in .socket/manifest.json (or use get/scan --mode vendored)
socket-patch vendor --json # vendor_lockfile_version_unsupported (expected: a native patch is present)
# Follow the advice:
npm patch rm ms # package.json no longer has patchedDependencies
npm install # lockfileVersion is still 4
rm -rf node_modules && npm install # still 4
socket-patch vendor --json # vendor_lockfile_version_unsupported again, same text
# What actually works:
npm install --lockfile-version 3 # lockfileVersion 3
socket-patch vendor --json # applied
rm -rf node_modules && npm ci # left-pad installs the patched bytesI drove vendor with the repo's prebuilt patch-service fixture (tests/prebuilt_common) over the real installed bytes. Every npm step is a real npm install.
Expected vs actual
- Expected: a refusal's remedy, followed literally, clears the refusal. docs/testing/npm-compatibility.md ("npm 12 notes") documents the refusal as "naming
npm patch". The remedy should name a step that downgrades the lock, such asnpm install --lockfile-version 3oncepatchedDependenciesis gone. Alternatively, the gate could accept a v4 lock that has nopatchedDependenciesand nopatchedrecords, since that lock has the v3 shape. - Actual: the remedy ("remove the
patchedDependenciesentries and regenerate the lock withnpm install") leaves the lock at v4, and vendoring refuses forever with the same text.
Matrix (Linux, Node 22.22, main e76cb9b)
| npm | lfv after npm patch |
after npm patch rm + npm install |
after rm -rf node_modules + npm install |
vendor after the advice |
after npm install --lockfile-version 3 |
|---|---|---|---|---|---|
| 12.2.0 | 4 | 4 | 4 | refused (repro ×2) | 3, vendor applied, npm ci patched |
| 12.1.0 | 4 | 4 | 4 | refused | 3, vendor applied |
npm <= 12.0 never writes v4, so it isn't affected. macOS and Windows weren't probed (the routine's probe branches are blocked); the behaviour is npm's lock writer plus a platform-independent text.
Suspect code
crates/socket-patch-core/src/vendor/npm_lock.rs:449-457(lock_version_gate, the v4 detail text)- The gate keys only on
lockfileVersion == 4(npm_lock.rs:442), not on whetherpatchedDependencies/patchedrecords still exist.
No probe runs: Linux only.
Activity
mikolalysenko commentedon Oct 15, 2026
[agent] Triage: confirmed on
main(544df96).lock_version_gate(crates/socket-patch-core/src/vendor/npm_lock.rs:442-457) refuses anylockfileVersion: 4lock. Its detail still tells the user to "regenerate the lock withnpm install", which keeps the lock at v4. The comment four lines above the detail says as much. No open or merged PR touches this. Labelledpriority:p1(npm). This isn't a duplicate of #1072: that issue is aboutvendor --revertwith a lost ledger, not about the lockfile gate.Generated by Claude Code
mikolalysenko commentedon Oct 21, 2026
[agent] Claiming this issue (shared root cause: the lockfileVersion 4 refusal's remedy names
npm install, which keeps the lock at v4). Branch: agent/fix-npm-v4-lock-remedy. Claim-ID: 2026-10-21T02:21:22Z-3152ccGenerated by Claude Code
mikolalysenko commentedon Oct 21, 2026
[agent] Draft PR: #1651
Generated by Claude Code
Fix npm v4 lock refusal advice that loops
Read package.json for the v4 native-patch check
Don't block on a FIFO at package.json