-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
Is there an existing issue for this?
- I have searched the existing issuesTo pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
This issue exists in the latest npm version
- I am using the latest npmTo pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Current Behavior
Consider a package, lib1
, with the following characteristics.
- has an
optionalDependency
, with an OS constraint, such asfsevents
package.json
{ ... "os": [ "darwin" ] ... }
- published with a shrinkwrap package descriptor
- shrinkwrap was generated on the platform compatible with the OS-constrained dependency
Developer A creates another package, app1
, which depends on lib1
, and generates app1
's package-lock.json
with npm install
also on the platform matching said OS constraint.
Developer B, OR a CI process, on a different platform from said OS constraint, runs npm ci
to install app1
's dependencies. npm ci
produces an error like the following.
[.../app1> npm ci
npm error code EBADPLATFORM
npm error notsup Unsupported platform for fsevents@2.3.3: wanted {"os":"darwin"} (current: {"os":"linux"})
npm error notsup Valid os: darwin
npm error notsup Actual os: linux
npm error A complete log of this run can be found in: /root/.npm/_logs/2024-07-02T12_41_06_204Z-debug-0.log
Examining app1
's package-lock.json
reveals that npm does not include an "optional": true
entry in the package-lock block for lib1
's fsevents
dependency.
Expected Behavior
npm ci
should retain the optional nature of the platform-specific dependency and proceed with a successful clean install of app1
's dependencies regardless of the dependencies.
Steps To Reproduce
- On a linux platform, clone the demo repository: https://github.com/restjohn/issues.npm.shrinkwrap_optional_dep.
- Use npm 10.8.1, latest at the time of this writing.
cd app1
npm ci
- npm should produce an error as in the Current Behavior section above.
Please see the README in the demo repository for quite a bit more detail about the nuances of this behavior.
Also note that the demo repository package lib1.shrinkwrap
references the fsevents
package through a devDependency, and npm should not be attempting to install lib1.shrinkwrap
devDependencies from the app1
package anyway.
Environment
- npm: 10.8.1
- Node.js: 20.15.0
- OS Name: Debian GNU/Linux 12 (bookworm)
- System Model Name: Node 20 Slim Docker image
- npm config:
; node bin location = /usr/local/bin/node
; node version = v20.15.0
; npm local prefix = /npm_transitive_os_dep/app1
; npm version = 10.8.1
; cwd = /npm_transitive_os_dep/app1
; HOME = /root
; Run `npm config ls -l` to show all defaults.
Activity
[-][BUG] `npm ci` erroneously installs optional OS-constrained transitive dependency[/-][+][BUG] `npm ci` erroneously installs optional OS-constrained transitive dependency through direct shrinkwrap dependency[/+][plugins/arcgis] manually add optional and dev flags to fsevents dep …
restjohn commentedon Jul 4, 2024
Aside from the problem of forcing installation of an optional dependency, another cause of this bug is that npm is installing the dev dependencies from the shrinkwrapped package. Apparently this is quite a long-standing issue.
Plugin actions (#210)
npm ci
doesn't work with decktape@3.13.0 astefanutti/decktape#341restjohn commentedon Aug 14, 2024
Others are having issues with shrinkwrap as well: #4323.
Skosche3 commentedon Nov 26, 2024
This is causing same issue in project I am working. Would love to see this fixed.
[RELEASE] 6.3.0-beta.8 (#268)
YodaDaCoda commentedon May 20, 2025
I've been experiencing this issue & have attempted to debug what's going on in the
npm
internals. There's a few semi-related issues (#6138 #4323 #2921) but this one is the most recent so I'm leaving my thoughts here.I've tried to attack this from a variety of angles, comparing the ideal tree with the existing tree, trying to understand how arborist's build-ideal-tree.js and reify.js stuff all comes together, etc.
It seems that in processing the shrinkwrap, if a dep is determined to be extraneous then none of the other attributes are retained.
cli/workspaces/arborist/lib/shrinkwrap.js
Lines 267 to 282 in 9cb9d50
In my particular case, the problematic dependancy is
optional=true
,dev=true
. I haven't yet locked down how it ends up marked extraneous - might be related to reset-dep-flags.jsI had success modifying one line where the packages in the tree are checked for buildability - being unfamiliar with the
npm
codebase, I'm not sure if this is the Most Correct way of fixing this. It does allownpm ci
to work on @restjohn'sapp1
package though.cli/workspaces/arborist/lib/arborist/build-ideal-tree.js
Line 197 in 9cb9d50
fix(arborist): don't checkEnging/checkPlatform for extraneous deps
5 remaining items