Skip to content

[BUG] Workspace Bin Hoisting Collision causes incorrect binary execution via npm exec #9712

Description

@arjun-vegeta

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

This is not just a request to bump a dependency for a CVE

  • This is not solely 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

  1. Create a monorepo with two workspaces: workspace-a and workspace-b.
  2. Install dep-1 (which exports a bin named my-cli) into workspace-a.
  3. Install dep-2 (which also exports a bin named my-cli) into workspace-b.
  4. 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/.
  5. Run npm exec -w workspace-b -- my-cli (the one that "lost" the race).
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bugthing that needs fixingNeeds Triageneeds review for next steps

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions