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
fix(arborist): skip lockfile entries for optional deps with incomplete manifests (npm#9343)
### What
When using a proxy/upstream registry (e.g. Azure Artifacts), npm 11
writes lockfile entries for platform-specific optional dependencies
without `version`, `resolved`, or `integrity` fields. Subsequent `npm
ci` fails with `Invalid Version:` errors.
Example broken lockfile entry:
```json
"node_modules/@esbuild/aix-ppc64": {
"optional": true
}
```
### Why
`#fetchManifest()` in `build-ideal-tree.js` fetches manifests for ALL
platform variants of optional dependencies. Proxy registries that
haven't cached packages for non-current platforms return incomplete
metadata (missing `version` field). npm creates a Node with empty
`pkg.version`, and `metaFromNode()` writes `{"optional": true}` to the
lockfile without version.
npm 10 never attempted to resolve non-current-platform variants, so this
only affects npm 11+.
### How
Two-layer defense:
1. **`build-ideal-tree.js` (`#nodeFromSpec`)**: When a registry manifest
lacks a `version` field, treat it as an `EINCOMPLETEMANIFEST` load
failure so that `#pruneFailedOptional()` marks it inert. Only applies to
`spec.registry` specs (not `file:` dependencies which may legitimately
omit version).
2. **`shrinkwrap.js` (`commit()`)**: Skip writing entries where the node
is optional, has no version, and is not the root. This acts as a
defense-in-depth layer.
### Testing
- Unit test added to `workspaces/arborist/test/shrinkwrap.js` —
simulates proxy registry scenario where an optional dep node has no
version
- All existing tests pass (`shrinkwrap.js` 45/45, `build-ideal-tree.js`
114/114)
- Manually verified with Azure Artifacts upstream proxy feed:
- Before fix: 46 broken lockfile entries (optional deps without version)
- After fix: 0 broken entries
- Output matches npm 10 behavior
Closesnpm#9342
---------
Co-authored-by: Michael Smith <owlstronaut@github.com>
0 commit comments