path-shadowed-npm-binary-changes-resolution-semantics
Diagnosis complete and verified. The solution is written to ~/npm-path-shadowing-solution.md.
Your described artifacts aren't currently materialized on this box, but the exact failure class is latent and reproducible:
/usr/bin/npm, node v22.23.2 at /usr/bin/node.~/.local/bin/{node,npm,npx} are dangling symlinks into the missing ~/.hermes/node/bin/*, and ~/.local/bin is on PATH ahead of /usr/bin. The moment that target (or a vite-plus/bin) reappears, it shadows the system toolchain.vp shim symlinked as npm/node/bun in a first-on-PATH dir intercepts the names. npm -v is answered by the shim (12.0.2), so a normal version check never sees the swap.#!/usr/bin/env node script. I verified that invoking the real npm by absolute path is still hijacked — /usr/bin/npm -v returned the shim's node output, because env resolves node through PATH. The only safe pin controls both the entry point and the interpreter.I reproduced the shim, confirmed which -a npm exposes it, confirmed the ~/.npm/_logs verbose cli line names the actual binary and that the shim writes no log, and verified a hardened gate that refuses/self-heals.
PATH (drop known shim dirs, prepend real bin), then hard-pin with "$REAL_NODE" "$REAL_NPM" "$@" so env node can't hijack it.node/npm/resolved targets at start and re-assert before each phase; abort on a mid-run PATH flap.~/.local/bin links, plus find the rc file that prepends them.which -a + readlink -f + per-candidate version, and the npm debug log's verbose cli/cwd/node/npm lines. Acceptance checklist included.Reproduction artifacts remain in /tmp/repro/ if you want to re-run the proofs.
# Evidence - Problem class: path-shadowed-npm-binary-changes-resolution-semantics - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T10:24:02.480Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A toolchain shim directory placed first on PATH (here ~/.local/share/vite-plus/bin, provably symlinking node/bun/npm to the vite-plus 'vp' binary, which reports npm 12.0.2) shadows the real npm 10.9.8 installed under ~/.hermes/node/bin. Symptom: identical npm commands on identical inputs produce OPPOSITE outcomes in the same session (one arm resolves an outdated dep set, the other crashes), and the resulting bisect chases fabricated causes such as 'the pnpm-lock.yaml causes the crash' that re-testing disproves. Nothing in a normal `npm -v` check catches it because the shim answers the version query too. Detection: print `which -a npm` plus the resolved version for EVERY candidate, and read the npm debug log's own 'verbose cwd / npm version' lines from ~/.npm/_logs to see which binary actually ran; in the head-to-head, pin the real binary by absolute path. Also verify which node binary the shim wraps - a PATH-flap mid-session silently splits a run between two package managers' semantics.", "environment": "linux", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "path-shadowed-npm-binary-changes-resolution-semantics", "provider": "openrouter", "solved_at": "2026-09-19T10:24:02.481Z", "version": ""}Diagnosis complete and verified. The solution is written to ~/npm-path-shadowing-solution.md.
Your described artifacts aren't currently materialized on this box, but the exact failure class is latent and reproducible:
/usr/bin/npm, node v22.23.2 at /usr/bin/node.~/.local/bin/{node,npm,npx} are dangling symlinks into the missing ~/.hermes/node/bin/*, and ~/.local/bin is on PATH ahead of /usr/bin. The moment that target (or a vite-plus/bin) reappears, it shadows the system toolchain.vp shim symlinked as npm/node/bun in a first-on-PATH dir intercepts the names. npm -v is answered by the shim (12.0.2), so a normal version check never sees the swap.#!/usr/bin/env node script. I verified that invoking the real npm by absolute path is still hijacked — /usr/bin/npm -v returned the shim's node output, because env resolves node through PATH. The only safe pin controls both the entry point and the interpreter.I reproduced the shim, confirmed which -a npm exposes it, confirmed the ~/.npm/_logs verbose cli line names the actual binary and that the shim writes no log, and verified a hardened gate that refuses/self-heals.
PATH (drop known shim dirs, prepend real bin), then hard-pin with "$REAL_NODE" "$REAL_NPM" "$@" so env node can't hijack it.node/npm/resolved targets at start and re-assert before each phase; abort on a mid-run PATH flap.~/.local/bin links, plus find the rc file that prepends them.which -a + readlink -f + per-candidate version, and the npm debug log's verbose cli/cwd/node/npm lines. Acceptance checklist included.Reproduction artifacts remain in /tmp/repro/ if you want to re-run the proofs.
# Evidence - Problem class: path-shadowed-npm-binary-changes-resolution-semantics - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T10:24:02.480Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A toolchain shim directory placed first on PATH (here ~/.local/share/vite-plus/bin, provably symlinking node/bun/npm to the vite-plus 'vp' binary, which reports npm 12.0.2) shadows the real npm 10.9.8 installed under ~/.hermes/node/bin. Symptom: identical npm commands on identical inputs produce OPPOSITE outcomes in the same session (one arm resolves an outdated dep set, the other crashes), and the resulting bisect chases fabricated causes such as 'the pnpm-lock.yaml causes the crash' that re-testing disproves. Nothing in a normal `npm -v` check catches it because the shim answers the version query too. Detection: print `which -a npm` plus the resolved version for EVERY candidate, and read the npm debug log's own 'verbose cwd / npm version' lines from ~/.npm/_logs to see which binary actually ran; in the head-to-head, pin the real binary by absolute path. Also verify which node binary the shim wraps - a PATH-flap mid-session silently splits a run between two package managers' semantics.", "environment": "linux", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "path-shadowed-npm-binary-changes-resolution-semantics", "provider": "openrouter", "solved_at": "2026-09-19T10:24:02.481Z", "version": ""}