Skip to content

Security updates are skipped for dependencies nested inside an npm workspace #16491

Open

Description

@untitaker

Is there an existing issue for this?

  • I have searched the existing issues

Package ecosystem

npm

Package manager version

npm 10.9.2 (also 11.x)

Language version

nodejs 22.17.1

Manifest location and content before the Dependabot update

package.json:

{
  "name": "dependabot-workspace-transitive-repro",
  "version": "1.0.0",
  "private": true,
  "workspaces": ["packages/a", "packages/b"]
}

packages/a/package.json:

{
  "name": "@repro/a",
  "version": "1.0.0",
  "private": true,
  "dependencies": { "minimatch": "^9.0.0" }
}

packages/b/package.json:

{
  "name": "@repro/b",
  "version": "1.0.0",
  "private": true,
  "dependencies": { "minimatch": "^3.0.0" }
}

package-lock.json (must be used as given; a fresh npm install from the
manifests above resolves to the patched 1.1.21):

{
  "name": "dependabot-workspace-transitive-repro",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "dependabot-workspace-transitive-repro",
      "version": "1.0.0",
      "workspaces": [
        "packages/a",
        "packages/b"
      ]
    },
    "node_modules/@repro/a": {
      "resolved": "packages/a",
      "link": true
    },
    "node_modules/@repro/b": {
      "resolved": "packages/b",
      "link": true
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "license": "MIT"
    },
    "node_modules/brace-expansion": {
      "version": "2.1.7",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
      "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
      "license": "MIT",
      "dependencies": {
        "balanced-match": "^1.0.0"
      }
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
      "license": "MIT"
    },
    "node_modules/minimatch": {
      "version": "9.0.9",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
      "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
      "license": "ISC",
      "dependencies": {
        "brace-expansion": "^2.0.2"
      },
      "engines": {
        "node": ">=16 || 14 >=14.17"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "packages/a": {
      "name": "@repro/a",
      "version": "1.0.0",
      "dependencies": {
        "minimatch": "^9.0.0"
      }
    },
    "packages/b": {
      "name": "@repro/b",
      "version": "1.0.0",
      "dependencies": {
        "minimatch": "^3.0.0"
      }
    },
    "packages/b/node_modules/brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "license": "MIT",
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "packages/b/node_modules/minimatch": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
      "license": "ISC",
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    }
  }
}

dependabot.yml content

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

Updated dependency

brace-expansion, 1.1.11 → 1.1.21 (advisory range <= 1.1.20)

What you expected to see, versus what you actually saw

In a repo using npm workspaces, Dependabot opens no security PR for a vulnerable
transitive package that npm placed inside a workspace directory, e.g.
packages/b/node_modules/brace-expansion. The job reports
security_update_not_possible and fails:

The latest possible version that can be installed is 1.1.11 because of the following conflicting dependencies:

  minimatch@9.0.9 requires brace-expansion@^2.0.2
  The lockfile might be out of sync?
The earliest fixed version is 1.1.21.

The lockfile is not out of sync. It is what npm install produced, and
npm ls --all reports no problems. minimatch@9.0.9 is a different copy in a
different workspace (packages/a), already on a patched brace-expansion@2.1.7;
it does not constrain packages/b's nested 1.x copy.

Expected: a lockfile-only PR bumping the nested copy to the patched version,
which is what npm audit fix does.

Native package manager behavior

npm audit fix works fine to bump it

Images of the diff or a link to the PR, issue, or logs

No response

Smallest manifest that reproduces the issue

The above manifests are already minimized to show the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions