You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] npm install incorrectly prunes unhoisted transitive optional dependencies when using workspaces #8536
have multiple versions of transitive optional dependencies in a workspace (e.g. vite -> esbuild -> @esbuild/darwin-arm64, and vitest -> vite -> esbuild -> @esbuild/darwin-arm64)
have dependency in the root package that also has those transitive optional dependencies via a peer dependency
Then:
running npm install will prune the unhoisted versions, and possibly fail. esbuild in particular uses a postinstall script to do introspection of its expected optional dependencies, and it will blow up if they are missing/wrong
Expected Behavior
Running npm install should not prune transitive optional dependencies. This works correctly on npm 11.4.2 and below.
npm error code 1
npm error path /path/to/npm-install-loses-transitive-peer-deps/node_modules/vitest/node_modules/esbuild
npm error command failed
npm error command sh -c node install.js
npm error /path/to/npm-install-loses-transitive-peer-deps/node_modules/vitest/node_modules/esbuild/install.js:133
npm error throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`);
npm error ^
npm error
npm error Error: Expected "0.21.5" but got "0.18.20"
npm error at validateBinaryVersion (/path/to/npm-install-loses-transitive-peer-deps/node_modules/vitest/node_modules/esbuild/install.js:133:11)
npm error at /path/to/npm-install-loses-transitive-peer-deps/node_modules/vitest/node_modules/esbuild/install.js:283:5
npm error
npm error Node.js v22.18.0
This is because esbuild's postinstall script does some sanity checks to ensure its platform-specific optional dependency is there. Because of the bug, 0.21.5 is not installed, so it finds the hoisted version and throws the error.
Alternative repro:
Run npm install --ignore-scripts
While it will "succeed", note that package-lock.json has now lost the unhoisted versions of all those optional dependencies, and they are not installed
Additional notes:
I tried to distill this down to a simpler repro, perhaps it could be taken further. There do seem to be at least a few conditions to trigger the bug:
You have to be using workspaces
The workspaces need to have two different versions of some transitive optional dependencies
The root package needs a dependency, that has a peer dependency, that also has the transitive optional dependencies (unclear if the version matters)
I've confirmed the bug is present in npm 11.5.0 onward, and is not present in npm 11.4.2 or earlier. So perhaps this PR is the culprit.
In my repro repo, the root package dependency uses a file URL to point at a tarball in the same repo, but the bug also happens for packages fetched from the registry (that's where I first encountered it)
Activity
jenseng commentedon Aug 28, 2025
Looks like this is a duplicate of #8489, I missed it in my initial search