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

Activity

  1. added a commit that references this issue on Jun 26, 2026
    719de1e
  2. added a commit that references this issue on Jun 26, 2026
    968e42f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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