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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions