Skip to content

[BUG] overrides for a transitive dependency are dropped when it is reached through a file:/workspace link #9659

Description

@manzoorwanijk

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

This is not just a request to bump a dependency for a CVE

  • This is not solely a request to bump a dependency for a CVE

Current Behavior

A root overrides entry that targets a transitive dependency is silently ignored when the path to that dependency crosses a file: (or workspace) link boundary.
The transitive dependency is installed at its original, un-overridden version, and the lockfile records that wrong version.
No warning or error is emitted.

Given a root that depends on a local package via file:, where the local package pulls a registry dependency with its own transitive dependency, an override on the transitive dependency has no effect.

// package.json
{
  "name": "root",
  "version": "1.0.0",
  "dependencies": { "a": "file:./pkgs/a" },
  "overrides": { "brace-expansion": "2.0.1" }
}
// pkgs/a/package.json
{ "name": "a", "version": "1.0.0", "dependencies": { "glob": "7.2.0" } }

After npm install, the lockfile pins brace-expansion@1.1.15 instead of the overridden 2.0.1:

node_modules/brace-expansion => 1.1.15   // WRONG, override ignored

The same wrong result occurs under both install-strategy=hoisted and install-strategy=linked, so this is not specific to the linked strategy.

For contrast, the identical override works when the dependency chain does NOT cross a link boundary.
Declaring glob as a direct dependency of the root (instead of via the file: package) correctly pins brace-expansion@2.0.1.

Expected Behavior

The override should apply regardless of whether the overridden dependency is reached through a file:/workspace link.
brace-expansion should be installed and locked at 2.0.1, matching the behavior when the same dependency is reached without crossing a link boundary, and matching the hoisted/registry-only result.

Steps To Reproduce

  1. Create a project whose package.json declares "dependencies": { "a": "file:./pkgs/a" } and "overrides": { "brace-expansion": "2.0.1" }.
  2. Create pkgs/a/package.json with "dependencies": { "glob": "7.2.0" } (glob pulls minimatch which depends on brace-expansion@^1.1.7).
  3. Run npm install.
  4. Inspect the installed/locked brace-expansion version: it is 1.1.15, not the overridden 2.0.1.
  5. Replace the file: dependency with a direct "glob": "7.2.0" dependency on the root and reinstall: brace-expansion is now correctly 2.0.1.

Environment

  • npm: 12.0.0-pre.1 (latest branch)
  • Node.js: v24.17.0
  • OS Name: macOS (Darwin 25.5.0)
  • System Model Name: Mac17,6
  • npm config:
install-strategy = hoisted   ; also reproduces with linked

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bugthing that needs fixingNeeds Triageneeds review for next steps

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions