Skip to content

fix(exec): don't inherit global config when installing to the npx cache - #9894

Open
lazerg wants to merge 2 commits into
npm:latestfrom
lazerg:fix/9890-npx-cache-global
Open

fix(exec): don't inherit global config when installing to the npx cache#9894
lazerg wants to merge 2 commits into
npm:latestfrom
lazerg:fix/9890-npx-cache-global

Conversation

@lazerg

@lazerg lazerg commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

What / Why

An npx spawned from a lifecycle script during npm install -g inherits npm_config_global=true from the script environment, so exec() builds the npx cache Arborist with global: true. On reify the installed package counts as a global top-level install, and bin-links puts the symlinks in <npxCache>/bin rather than <installDir>/node_modules/.bin, which is the only path exec() adds to binPaths. A warm npx cache hides the problem because nothing is reified.

On npm 10.x that surfaces the way the issue reports it, as command not found and a rollback of the whole global install. Since npm 11.2 the failure comes a step earlier: global mode also skips saving the ideal tree, so the PackageJson.load(installDir) after reify throws Could not read package.json ... npxCache/<hash>/package.json. Same cause either way.

The npx cache is never a global install, so its Arborist now sets global: false explicitly.

Testing

New case in workspaces/libnpmexec/test/registry.js that runs exec with global: true and checks the bins end up in the cache entry's node_modules/.bin and not at the cache root. It fails on the current code and passes with the fix.

Also checked by hand with a cold cache: npm_config_global=true node . exec --yes -- cowsay hello errors on latest and works after the change.

References

Fixes #9890

@lazerg
lazerg requested review from a team as code owners August 18, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

npm exec (npx) links bins to the wrong directory when run from a global install's lifecycle script, causing "command not found" and install rollback

1 participant