Skip to content

fix(arborist): skip engine validation for omitted dependencies#9145

Open
Max1mus5 wants to merge 2 commits intonpm:latestfrom
Max1mus5:hfi/883ffa3e-5d80-4c07-8157-0fded901fcac/B
Open

fix(arborist): skip engine validation for omitted dependencies#9145
Max1mus5 wants to merge 2 commits intonpm:latestfrom
Max1mus5:hfi/883ffa3e-5d80-4c07-8157-0fded901fcac/B

Conversation

@Max1mus5
Copy link

Summary

  • Bug: npm install --omit=dev --engine-strict crashes with EBADENGINE when a devDependency declares incompatible engine requirements. The engine/platform check only skipped optional deps, not deps excluded via --omit.
  • Fix: Centralize the omit-matching logic into a stateless Node.shouldOmit(omitSet) predicate on the base Node class and call it from build-ideal-tree, reify, and audit-report. The method accepts both Set and Array inputs, caches nothing on the node, and correctly handles devOptional nodes (omitted only when both dev and optional are in the set).
  • Cleanup: Remove the three individual #omitDev/#omitPeer/#omitOptional private fields from reify.js in favor of a single #omitSet. Pin all @npmcli/arborist dependency versions to exact ranges.

Test plan

  • test/node.js — 8 subtests for shouldOmit: boundary (null/undefined/empty), per-type (dev/optional/peer), devOptional (6 combinations proving the both-required rule), array coercion, and statelessness across sequential calls
  • test/arborist/build-ideal-tree.js — 2 new integration tests: omitted dev dep skips engine check; non-omitted dev dep still throws EBADENGINE
  • test/audit-report.js — full 20-test suite passes (refactor regression)
  • test/arborist/reify.js — omit-related tests pass (refactor regression)
  • ESLint passes on all changed files

🤖 Generated with Claude Code

PR Writer and others added 2 commits March 23, 2026 20:31
Problem: Running `npm install --omit=dev --engine-strict` crashes with
EBADENGINE when a devDependency declares incompatible engine requirements.
The engine/platform check in `#checkEngineAndPlatform` only skipped
optional deps, not deps excluded via the --omit flag.  Additionally,
the logic determining whether a node should be omitted was duplicated
across three modules (build-ideal-tree, reify, audit-report).

Solution: Centralize the omit-matching logic into a stateless
`Node.shouldOmit(omitSet)` predicate and call it from all three
consumers.  The method accepts both Set and Array inputs, caches
nothing on the node, and documents the devOptional semantics: a node
in the overlap of the dev and optional trees is only omitted when
both 'dev' and 'optional' are in the set.

- build-ideal-tree: gate engine/platform checks on shouldOmit
- reify: replace #omitDev/#omitPeer/#omitOptional with single #omitSet
- audit-report: replace inline logic in shouldAudit with shouldOmit
- package.json: pin all dependency versions to exact ranges
- tests: unit tests for shouldOmit (boundary, coercion, statelessness)
  and integration tests for the engine-strict + omit-dev scenario

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Max1mus5 Max1mus5 requested a review from a team as a code owner March 24, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant