Skip to content

fix(arborist): skip re-resolution when audit fix requires semver-major bump#9543

Open
Zelys-DFKH wants to merge 2 commits into
npm:latestfrom
Zelys-DFKH:fix/audit-fix-skip-semver-major
Open

fix(arborist): skip re-resolution when audit fix requires semver-major bump#9543
Zelys-DFKH wants to merge 2 commits into
npm:latestfrom
Zelys-DFKH:fix/audit-fix-skip-semver-major

Conversation

@Zelys-DFKH

@Zelys-DFKH Zelys-DFKH commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What

npm audit fix was treating every edge to a vulnerable package as a "problem edge" requiring dep re-resolution, regardless of whether a fix is available within the current semver range. When the only fix requires a semver-major version bump (fixAvailable is { isSemVerMajor: true }) or no fix exists at all (fixAvailable is false), the re-resolution still ran and picked the latest in-range version, which is still vulnerable. A spurious minor or patch update landed in the lockfile without fixing anything.

Why

The check in #problemEdges in build-ideal-tree.js was unconditional: every vulnerable edge got flagged as a problem, with no consultation of vuln.fixAvailable to decide whether re-resolving would help.

How

Before pushing an edge as a problem, check vuln.fixAvailable. Only treat it as a problem if fixAvailable === true (a fix exists within the current semver range) or if --force is set (user explicitly wants out-of-range updates). The continue is preserved regardless, so there is no fallthrough to other checks.

A regression test covers the case: a dependency where all 2.x versions are vulnerable and the fix requires bumping to 3.0.0. audit fix (without --force) leaves the lockfile unchanged.

Fixes #9344

Credit to @36degrees for the detailed report.

…r bump

When npm audit fix encounters a vulnerable package whose only available fix
requires a semver-major version bump, #problemEdges was unconditionally
treating the edge as a "problem" and scheduling dep re-resolution. This
caused the latest in-range version to be installed even though it remains
vulnerable, producing a spurious minor/patch update with no security benefit.

Add a guard: only push the edge as a problem if vuln.fixAvailable === true
(a fix exists within the current semver range) or if --force is set. The
continue is preserved regardless, so there is no fallthrough to other checks.

Fixes npm#9344
@Zelys-DFKH Zelys-DFKH requested review from a team as code owners June 11, 2026 22:15
Adds a regression test that exercises the false branch of the
fixAvailable guard added in the preceding commit: when all in-range
versions of a vulnerable package are still vulnerable and the only fix
requires a semver-major bump, audit fix must leave the lockfile
unchanged.
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.

[BUG] npm audit makes unrelated minor/patch updates to packages that require a major update to fix

1 participant