Is there an existing issue for this?
This issue exists in the latest npm version
This is not just a request to bump a dependency for a CVE
Current Behavior
When two workspaces each depend on a different package that exports a binary with the exact same name, Arborist hoists both dependencies to the root node_modules/. However, because bin-links uses a "first-wins" mechanism, only one shim gets created in root/node_modules/.bin/.
As a result, when running npm exec -w <loser-workspace> -- <bin>, libnpmexec falls back to the root .bin folder and inadvertently executes the wrong binary (the one belonging to the other workspace's dependency) because a local .bin folder was never created for the workspace.
Expected Behavior
npm exec -w <workspace> should completely isolate identical binary names in a monorepo and always execute the binary that belongs to the target workspace's dependency tree, regardless of hoisting rules at the root.
Steps To Reproduce
- Create a monorepo with two workspaces:
workspace-a and workspace-b.
- Install
dep-1 (which exports a bin named my-cli) into workspace-a.
- Install
dep-2 (which also exports a bin named my-cli) into workspace-b.
- Observe that both dependencies hoist to the root. Only one of them (e.g.,
dep-1) gets its my-cli shim created in root/node_modules/.bin/.
- Run
npm exec -w workspace-b -- my-cli (the one that "lost" the race).
- See that
dep-1's script is executed instead of dep-2's script.
Environment
- npm:
12.0.0-pre.2
- Node.js:
v23.11.1
- OS Name:
macOS 15.7.7
- System Model Name:
MacBookPro18,1
- npm config:
; "user" config from /Users/arjun/.npmrc
//registry.npmjs.org/:_authToken = (protected)
; "project" config from /Users/arjun/Desktop/npm/.npmrc
package-lock = true
; node bin location = /Users/arjun/.nvm/versions/node/v23.11.1/bin/node
; node version = v23.11.1
; npm local prefix = /Users/arjun/Desktop/npm
; npm version = 12.0.0-pre.2
; cwd = /Users/arjun/Desktop/npm
; HOME = /Users/arjun
; Run `npm config ls -l` to show all defaults.
Is there an existing issue for this?
This issue exists in the latest npm version
This is not just a request to bump a dependency for a CVE
Current Behavior
When two workspaces each depend on a different package that exports a binary with the exact same name, Arborist hoists both dependencies to the root
node_modules/. However, becausebin-linksuses a "first-wins" mechanism, only one shim gets created inroot/node_modules/.bin/.As a result, when running
npm exec -w <loser-workspace> -- <bin>,libnpmexecfalls back to the root.binfolder and inadvertently executes the wrong binary (the one belonging to the other workspace's dependency) because a local.binfolder was never created for the workspace.Expected Behavior
npm exec -w <workspace>should completely isolate identical binary names in a monorepo and always execute the binary that belongs to the target workspace's dependency tree, regardless of hoisting rules at the root.Steps To Reproduce
workspace-aandworkspace-b.dep-1(which exports a bin namedmy-cli) intoworkspace-a.dep-2(which also exports a bin namedmy-cli) intoworkspace-b.dep-1) gets itsmy-clishim created inroot/node_modules/.bin/.npm exec -w workspace-b -- my-cli(the one that "lost" the race).dep-1's script is executed instead ofdep-2's script.Environment
12.0.0-pre.2v23.11.1macOS 15.7.7MacBookPro18,1