dependabot-core icon indicating copy to clipboard operation
dependabot-core copied to clipboard

Dependabot creates invalid update for npm due to "overriding peer dependency"

Open ahilke opened this issue 1 year ago • 5 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Package ecosystem

npm

Package manager version

9.6.7

Language version

v18.17.1

Manifest location and content before the Dependabot update

./package.json

{
    "name": "crap-score",
    "version": "1.2.0",
    "description": "Calculate and visualize the CRAP score of a JS/TS project using the provided `jest` integration, CLI, or API.",
    "license": "MIT",
    "keywords": [
        "CRAP Score",
        "Cyclomatic Complexity",
        "Code Quality",
        "Test Coverage"
    ],
    "author": {
        "name": "Arno Hilke",
        "email": "[email protected]"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/ahilke/js-crap-score.git"
    },
    "bugs": {
        "url": "https://github.com/ahilke/js-crap-score/issues"
    },
    "type": "module",
    "main": "./dist/index.js",
    "exports": "./dist/index.js",
    "types": "./dist/index.d.ts",
    "bin": {
        "crap": "./dist/crap.js"
    },
    "scripts": {
        "build": "nest build",
        "prepublishOnly": "npm run build",
        "start": "nest start",
        "start:dev": "nest start --watch",
        "start:debug": "nest start --debug",
        "start:prod": "node ./dist/main.js",
        "test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest",
        "test:dev": "npm run test -- --watch",
        "test:debug": "node --experimental-vm-modules --no-warnings --inspect ./node_modules/.bin/jest --runInBand",
        "test:cov": "npm run test -- --coverage",
        "test:generate-data": "npm run test -- --config=./test-data/esm/jest.config.ts && jest --config=./test-data/cjs/jest.config.ts",
        "prettier": "prettier --write ."
    },
    "engines": {
        "node": ">=18.17.1",
        "npm": ">=9.6.7"
    },
    "dependencies": {
        "@nestjs/cli": "^10.1.18",
        "@nestjs/common": "^10.2.7",
        "@nestjs/core": "^10.2.7",
        "@types/inquirer": "^8.2.9",
        "@typescript-eslint/parser": "^6.8.0",
        "@typescript-eslint/utils": "^6.8.0",
        "eslint": "^8.51.0",
        "handlebars": "^4.7.8",
        "lodash-es": "^4.17.21",
        "nest-commander": "^3.11.1",
        "reflect-metadata": "^0.1.13",
        "rxjs": "^7.8.1"
    },
    "devDependencies": {
        "@jest/reporters": "^29.7.0",
        "@jest/test-result": "^29.7.0",
        "@nestjs/testing": "^10.2.7",
        "@types/lodash-es": "^4.17.10",
        "prettier": "^3.0.3",
        "ts-jest": "^29.1.1",
        "ts-node": "^10.9.1",
        "typescript": "^5.2.2"
    }
}

https://github.com/ahilke/js-crap-score/blob/bf7a32705e23a1f7733493b7be9d4573ce3dfee2/package.json

dependabot.yml content

./.github/dependabot.yml

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

https://github.com/ahilke/js-crap-score/blob/bf7a32705e23a1f7733493b7be9d4573ce3dfee2/.github/dependabot.yml

Updated dependency

nest-commander from 3.11.1 to 3.12.0.

What you expected to see, versus what you actually saw

A PR was created to bump nest-commander from 3.11.1 to 3.12.0. This creates an invalid dependency tree. When checked out and running npm ci locally, it produces the following warnings:

% npm ci
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @fig/[email protected]
npm WARN Found: [email protected]
npm WARN node_modules/nest-commander/node_modules/commander
npm WARN   commander@"11.0.0" from [email protected]
npm WARN   node_modules/nest-commander
npm WARN     nest-commander@"^3.11.1" from the root project
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer commander@"^8.0.0" from @fig/[email protected]
npm WARN node_modules/nest-commander/node_modules/@fig/complete-commander
npm WARN   @fig/complete-commander@"^2.0.1" from [email protected]
npm WARN   node_modules/nest-commander
npm WARN 
npm WARN Conflicting peer dependency: [email protected]
npm WARN node_modules/commander
npm WARN   peer commander@"^8.0.0" from @fig/[email protected]
npm WARN   node_modules/nest-commander/node_modules/@fig/complete-commander
npm WARN     @fig/complete-commander@"^2.0.1" from [email protected]
npm WARN     node_modules/nest-commander

When running npm ls commander, it shows the invalid dependency resolution:

npm ls commander
npm ERR! code ELSPROBLEMS
npm ERR! invalid: [email protected] /Users/arnohilke/projects/js-crap-score/node_modules/nest-commander/node_modules/commander
[email protected] /Users/arnohilke/projects/js-crap-score
├─┬ @nestjs/[email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └─┬ [email protected]
│     └─┬ [email protected]
│       └── [email protected]
└─┬ [email protected]
  ├─┬ @fig/[email protected]
  │ └── [email protected] deduped invalid: "^8.0.0" from node_modules/nest-commander/node_modules/@fig/complete-commander
  └── [email protected] invalid: "^8.0.0" from node_modules/nest-commander/node_modules/@fig/complete-commander

While I'm aware there could be an issue with npm or the related packages producing the invalid dependency tree in the first place, I'd expect Dependabot to not create invalid updates or at least create some sort of warning. Since there is no way to bump nest-commander with a valid dependency tree, I expect no PR to be opened or at least some sort of warning within the PR.

Native package manager behavior

A manual update produce the same warning as above:

% npm install --save nest-commander@latest 
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @fig/[email protected]
npm WARN Found: [email protected]
npm WARN node_modules/nest-commander/node_modules/commander
npm WARN   commander@"11.0.0" from [email protected]
npm WARN   node_modules/nest-commander
npm WARN     nest-commander@"3.12.0" from the root project
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer commander@"^8.0.0" from @fig/[email protected]
npm WARN node_modules/nest-commander/node_modules/@fig/complete-commander
npm WARN   @fig/complete-commander@"^2.0.1" from [email protected]
npm WARN   node_modules/nest-commander
npm WARN 
npm WARN Conflicting peer dependency: [email protected]
npm WARN node_modules/commander
npm WARN   peer commander@"^8.0.0" from @fig/[email protected]
npm WARN   node_modules/nest-commander/node_modules/@fig/complete-commander
npm WARN     @fig/complete-commander@"^2.0.1" from [email protected]
npm WARN     node_modules/nest-commander

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

https://github.com/ahilke/js-crap-score/pull/28

Smallest manifest that reproduces the issue

{
  "dependencies": {
    "@nestjs/cli": "10.1.18",
    "nest-commander": "3.11.1"
  }
}

Using node 18.7.1 and npm 9.6.7, add this to an empty folder and run npm i to create a valid dependency tree. Run then npm i [email protected] to create the invalid dependency tree.

ahilke avatar Oct 20 '23 22:10 ahilke

Hello!

Thanks for the report, this is a bug.

The problem is that dependabot only detects first level peer dependency conflicts, but in this case, the relevant conflict is happening at the second level:

npm WARN Could not resolve dependency:
npm WARN peer commander@"^8.0.0" from @fig/[email protected]
npm WARN node_modules/nest-commander/node_modules/@fig/complete-commander
npm WARN   @fig/complete-commander@"^2.0.1" from [email protected]
npm WARN   node_modules/nest-commander

It's mainly the following line that's relevant to us, but we don't parse it:

npm WARN   @fig/complete-commander@"^2.0.1" from [email protected]

The relevant regex is here (and the code using it lives in that same file):

https://github.com/dependabot/dependabot-core/blob/be209fa2ad4f5c3cf6a76074ddf3b7a0247bcc87/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb#L69-L80

We should expand the logic so that we're able to scan all unmet peer dependencies, not just the first level.

deivid-rodriguez avatar Oct 24 '23 12:10 deivid-rodriguez

Can confirm. I just run this in Angular 17 repository, it caused conflicting peer dependency on 2 separate occassion.

jasonrichdarmawan avatar Feb 13 '24 08:02 jasonrichdarmawan

The problem is that dependabot only detects first level peer dependency conflicts, but in this case, the relevant conflict is happening at the second level:

In my case, it happen in the first level

run git checkout dependabot/npm_and_yarn/typescript-eslint/parser-7.0.1

branch 'dependabot/npm_and_yarn/typescript-eslint/parser-7.0.1' set up to track 'origin/dependabot/npm_and_yarn/typescript-eslint/parser-7.0.1'.
Switched to a new branch 'dependabot/npm_and_yarn/typescript-eslint/parser-7.0.1'

run npm ls @typescript-eslint/parser

npm ERR! code ELSPROBLEMS
npm ERR! invalid: @typescript-eslint/[email protected]
[email protected]
├─┬ @typescript-eslint/[email protected] invalid: "^6.19.0" from the root project
│ └── @typescript-eslint/[email protected] deduped invalid: "^7.0.1" from the root project
└── @typescript-eslint/[email protected] invalid: "^7.0.1" from the root project

run npm ci

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: @typescript-eslint/[email protected]
npm ERR! Found: @typescript-eslint/[email protected]
npm ERR! node_modules/@typescript-eslint/parser
npm ERR!   dev @typescript-eslint/parser@"^7.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @typescript-eslint/parser@"^6.0.0 || ^6.0.0-alpha" from @typescript-eslint/[email protected]
npm ERR! node_modules/@typescript-eslint/eslint-plugin
npm ERR!   dev @typescript-eslint/eslint-plugin@"^6.19.0" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: @typescript-eslint/[email protected]
npm ERR! node_modules/@typescript-eslint/parser
npm ERR!   peer @typescript-eslint/parser@"^6.0.0 || ^6.0.0-alpha" from @typescript-eslint/[email protected]
npm ERR!   node_modules/@typescript-eslint/eslint-plugin
npm ERR!     dev @typescript-eslint/eslint-plugin@"^6.19.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! 
npm ERR! For a full report see:

jasonrichdarmawanmereka avatar Feb 15 '24 03:02 jasonrichdarmawanmereka

Curious if anyone has come up with a work-around? (e.g. maybe making one of these conflicts explicit/top-level to appease dependabot?) We hit this with eslint-parser across 4 of our repos, rendering dependabot useless for npm updates unfortunately.

eseidel avatar May 27 '24 16:05 eseidel