Repository navigation
Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969
Description
[agent] Found by the scheduled npm bug-hunt routine (ledger #302).
Summary
npm 11.14.0 added allow-file (all / root / none; default all). It gates every dependency that resolves to a local tarball file. Vendored mode rewires package-lock.json entries to file:.socket/vendor/npm/<uuid>/<pkg>.tgz, which are exactly those specs. When the project's npm config sets allow-file=root and the vendored package is a transitive dependency, or sets allow-file=none for any vendored package, npm ci / npm install refuse the lock:
npm error code EALLOWFILE
npm error Fetching non-root packages of type "file" have been disabled # root
npm error Fetching packages of type "file" have been disabled # none
socket-patch doesn't look at allow-file at all. scan --mode vendored exits 0 with success and no warning, vendor --check passes, and lockfile-only vex attests not_affected. The first sign of trouble is the project's next install, in CI.
(allow-file=root does admit a vendored direct dependency. In the repro, left-pad installs patched under root and is-number, pulled in by to-regex-range, is refused.)
Impact
- A project that hardens its npm config, the same family of settings as npm 12's
allow-git=none/allow-remote=nonedefaults, gets a broken lock from a "successful" vendored scan, and every install fails until someone traces EALLOWFILE back to the vendoredfile:entries. - It fails closed (nothing unpatched is installed). But the run promises an installable commit, and
vendor --check, the verification gate, passes it. - The docs say the opposite:
docs/testing/npm-compatibility.md("allow-filedefaults toall: vendoredfile:tarballs install unchanged"),docs/ecosystems.mdand CLI_CONTRACT ("Vendored mode is unaffected … npm gates [file: specs] byallow-file(defaultall), neverallow-remote") cover only the default. Hosted mode has a full contract for the matchingallow-remotecase: it reads every npm config layer, and an explicit non-allvalue is respected and warned about (redirect_npm_allow_remote) with the install-time remedy.
Repro (Linux, main 9c43dfc, local mock patch API serving is-number@7.0.0 and left-pad@1.3.0)
mkdir t && cd t
echo '{"name":"t","version":"1.0.0","private":true,"dependencies":{"to-regex-range":"5.0.1","left-pad":"1.3.0"}}' > package.json
npm i
printf 'allow-file=root\n' > .npmrc # or allow-file=none
socket-patch scan --mode vendored --yes --json --api-url $MOCK --org test-org --api-token x
# exit 0, status success, vendor.summary.applied 2, warnings []
socket-patch vendor --check --json # exit 0, success
socket-patch vex -O vex.json --product pkg:npm/t@1.0.0 # exit 0, not_affected (from the lock, before any install)
rm -rf node_modules && npm ci --cache "$(mktemp -d)"
# npm error code EALLOWFILE / Fetching non-root packages of type "file" have been disabled; exit 1npm_config_allow_file=root npm ci (env layer, no .npmrc) fails the same way.
Expected vs actual
- Expected: treat
allow-filethe way hosted mode treatsallow-remote. If any npm config layer (project / user / global.npmrc,npm_config_allow_file) has an effectiveallow-fileofnone, orrootwhile a vendored entry isn't a root dependency, and the installed npm is ≥ 11.14, the vendored run should warn (or refuse) and name the setting and remedy (allow-file=allin.npmrc, ornpm ci --allow-file=all).vendor --checkshould flag the same thing, and the docs' "vendored is unaffected" claim should be scoped to the default. - Actual: silent success from
scan,vendor --checkandvex, then EALLOWFILE on every install.
OS × version
| OS | npm (Node) | allow-file |
scan / vendor --check |
npm ci |
|---|---|---|---|---|
| Linux | 12.2.0 (24.21) | root, transitive |
success, no warning (x2) | EALLOWFILE, exit 1 (x2) |
| Linux | 12.2.0 (24.21) | none |
success, no warning (x2) | EALLOWFILE, exit 1 (x2) |
| Linux | 12.2.0 (24.21) | root, direct dep only |
success | installs patched (pass) |
| Linux | 12.2.0 (24.21) | all (default) |
success | installs patched (pass) |
| Linux | 11.21.0 (22.22) | root / none |
success, no warning | EALLOWFILE, exit 1 |
| Linux | 10.9.4 / ≤ 11.13 | n/a (no such setting; checked npm 11.8 / 11.9 / 11.10 / 11.12 / 11.13 config definitions) | — | not affected |
| macOS / Windows | not probed | npm's own config gate, no OS-specific path |
First affected npm: 11.14.0, where allow-file first appears in @npmcli/config definitions. Not a socket-patch regression: no release has ever checked allow-file.
Suspect code
crates/socket-patch-core/src/vendor/npm_flavor.rs:343(vendor_npm_any): rewires lock entries tofile:specs without reading npm'sallow-file.crates/socket-patch-core/src/hosted/engine.rs:1405-1417(npm_allow_remote): the precedent (config-layer reader plusredirect_npm_allow_remotewarning). Its doc comment, andCLI_CONTRACT.md:117, state that vendored is unaffected becauseallow-filedefaults toall.crates/socket-patch-cli/src/commands/vendor.rs:1020-1046(vendor --checkwiring probe): passes the entry.
Related: #812 (hosted pin broken by replace-registry-host=always; the same "npm config makes the rewrite uninstallable, scan reports success" class).
Backlog review — 2026-10-08
Priority: P1 → P2. npm allow-file policy prevents the generated vendor install; npm fails closed with EALLOWFILE. Preserve the preflight fix.
Activity
npm: run 26 ledger (#969, #900 comment)
mikolalysenko commentedon Oct 7, 2026
[agent] Triaged as
priority:p1(npm). This is not a duplicate. Onmain(9c43dfc), nothing reads npm'sallow-file. The only mentions are the "vendored is unaffected (defaultall)" claims inCLI_CONTRACT.md:117,hosted/engine.rs:1416andtests/in_process_vendor.rs:3797. No open or merged PR addresses it.#812 is related but has a different cause: there, the hosted pin is broken by
replace-registry-host. The fix here can reuse hosted mode's npm config-layer reader (npm_allow_remoteinhosted/engine.rs) for the vendoredallow-filecheck.Generated by Claude Code
mikolalysenko commentedon Oct 7, 2026
Being fixed in draft PR #1008 (batch fix for open
pm:npmissues).Fix vendored npm wiring silently broken by npm allow-file (#969)
Document vendor_workspace_member_skipped and vendor_npm_allow_file co…
Fix allow-file unit tests reading the developer's npm config (#969)