fix(arborist): apply overrides across a file:/workspace link boundary#9671
Merged
owlstronaut merged 2 commits intoJun 26, 2026
Merged
Conversation
…IdealTree A root override for a transitive dep was dropped when the path to that dep crossed a file:/workspace link boundary, so the dep resolved to its un-overridden version. The link target's overrides were never forwarded before its subtree resolved. Forward them in #resolveLinks so descendant edges inherit the rule.
…Actual A file: link target's subtree resolves late, so repropagating overrides before edges were resolved missed the transitive match and npm ls reported the overridden edge as invalid. Run repropagation once all edges are resolved.
owlstronaut
approved these changes
Jun 26, 2026
Contributor
|
This usually means the cherry-pick had conflicts. Please create a manual backport: git fetch origin release/v11
git checkout -b backport/v11/9671 origin/release/v11
git cherry-pick -x 968e42fbd62eb3a6f446466359c9431f41d76b2b
# resolve any conflicts, then:
git push origin backport/v11/9671Error details |
Contributor
Author
|
Creating a manual backport... |
Contributor
Author
|
Here you go #9673 |
owlstronaut
pushed a commit
that referenced
this pull request
Jun 26, 2026
…v11) (#9673) Backport of #9671 to `release/v11`. A root `overrides` entry targeting a transitive dependency was silently dropped when the path to that dependency crossed a `file:`/workspace link, so the dependency resolved to its un-overridden version and the lockfile pinned the wrong version. It reproduced under both the `hoisted` and `linked` install strategies, while the same override applied correctly when the dependency was reached without crossing a link. `buildIdealTree` now forwards a link's overrides to its target before the target's subtree is resolved, so descendant edges inherit the rule as they are added, matching how a registry node always inherits its ancestor's `OverrideSet`. `loadActual` now repropagates overrides through links once all edges are resolved, so a transitive override reached through a `file:` link is reported as `overridden` rather than `invalid` by `npm ls`. Backport notes: clean cherry-pick except for the `#repropagateOverrides` comment, which conflicted only because `release/v11` does not have the adjacent `#applyPackageExtensions` method; resolved by keeping the v11 structure and applying the comment update. ## References Fixes #9659 Backport of #9671
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A root
overridesentry targeting a transitive dependency was silently dropped when the path to that dependency crossed afile:/workspace link, so the dependency resolved to its un-overridden version and the lockfile pinned the wrong version. It reproduced under both thehoistedandlinkedinstall strategies, while the same override applied correctly when the dependency was reached without crossing a link.Override rules propagate through dependency edges, but a Link and its target are not edge-connected, so they are bridged by forwarding the Link's
OverrideSetto its target. That forwarding ran while the target's subtree was still unbuilt, so its guard found no matching rule and never forwarded, leaving the target and its descendant edges without the rule.buildIdealTreenow forwards a link's overrides to its target before the target's subtree is resolved, so descendant edges inherit the rule as they are added, matching how a registry node always inherits its ancestor'sOverrideSet.loadActualnow repropagates overrides through links once all edges are resolved, so a transitive override reached through afile:link is reported asoverriddenrather thaninvalidbynpm ls.References
Fixes #9659