SIGN IN SIGN UP

fix(exec): prevent shared binPaths pollution across workspace runs (#9650)

**Description:**
related: #9640

**Bug:**
When running `npm exec` across multiple workspaces, the binary from the
first workspace would accidentally bleed into the second one if they
shared the same name.

**Root Cause:**
In `libnpmexec`, the `binPaths` array was scoped at the module level
instead of inside the `exec()` function. Since `execWorkspaces` runs
everything in a single process, `binPaths` just kept accumulating paths.
When the second workspace ran, the first workspace's `.bin` path was
still sitting at the front of `PATH`, so it hijacked the execution.

**Fix:**
Moved `binPaths` inside `exec()` so it gets a fresh array on every call.
I left the `manifests` map at the module level (keyed by `spec.raw`)
because we still want to cache registry specs across calls, and absolute
paths won't collide anyway.

**Testing:**
- Added a regression test in `test/local.js` with two workspaces using
the exact same local bin name (`shared-bin`).
- Gave each test call its own `args` array to stop `@npmcli/run-script`
from mutating it and hanging the tests.
- Fails correctly without the fix. With the fix, all tests pass 100%.
A
Arjun R committed
18b930f1abeb1b1154e9a51117bd11bffaa2ad94
Parent: 6da6555
Committed by GitHub <noreply@github.com> on 6/29/2026, 3:03:52 PM