Skip to content

[BUG] npm 7 makes incorrect suggestion when encountering peer deps issues #2123

Closed

Description

@billyjanitsch

Current Behavior:

When npm install fails due to peer dep incompatibilities, something like this is printed:

npm ERR! Found: webpack@5.4.0
npm ERR! node_modules/webpack
npm ERR!   dev webpack@"^5.4.0" from the root project
npm ERR!   peer webpack@">=4.43.0 <6.0.0" from @pmmmwh/react-refresh-webpack-plugin@0.4.3
npm ERR!   node_modules/@pmmmwh/react-refresh-webpack-plugin
npm ERR!     dev @pmmmwh/react-refresh-webpack-plugin@"^0.4.3" from the root project
npm ERR!   7 more (babel-loader, file-loader, html-webpack-plugin, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer webpack@"^4.0.0" from webpack-dev-middleware@3.7.2
npm ERR! node_modules/webpack-dev-server/node_modules/webpack-dev-middleware
npm ERR!   webpack-dev-middleware@"^3.7.2" from webpack-dev-server@3.11.0
npm ERR!   node_modules/webpack-dev-server
npm ERR!     dev webpack-dev-server@"^3.11.0" from the root project
npm ERR!     1 more (@pmmmwh/react-refresh-webpack-plugin)
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.

The suggestion to "retry this command with --force" doesn't appear to work. npm install --force prints exactly the same output, with only the addition of:

npm WARN using --force Recommended protections disabled.

Expected Behavior:

I would expect the suggested command to work, or I would expect it not to be suggested.

Steps To Reproduce:

  1. Run npm install webpack@5 webpack-dev-server@3.
  2. Run npm install --force webpack@5 webpack-dev-server@3, as suggested by the output of the first command.
  3. The second command fails with the same error, and the same suggestion to retry with --force.

Environment:

  • OS: macOS 10.15.7
  • Node: 14.14.0
  • npm: 7.0.8

Activity

  1. added
    Bugthing that needs fixing
    Needs Triageneeds review for next steps
    Release 7.xwork is associated with a specific npm 7 release
    on Nov 5, 2020
  2. kapoko commented on Nov 5, 2020

    @kapoko

    Reverting back to npm 6.14.8 solved this for me for now using npm install -g npm@latest

  3. ljharb commented on Nov 5, 2020

    @ljharb
    Contributor

    This isn’t a bug; it’s a correct warning because your dependency graph is invalid.

    you have webpack 5, but v3.7.2 of webpack-dev-middleware requires webpack 4. Your choices are to downgrade to webpack 4, upgrade to a version (of available) of webpack-dev-middleware that supports webpack 5, or remove webpack-dev-middleware entirely.

    The message telling you to use —force is misleading, yes, because this isn’t programmatically fixable.

  4. billyjanitsch commented on Nov 5, 2020

    @billyjanitsch
    Author

    This isn’t a bug; it’s a correct warning because your dependency graph is invalid.

    @ljharb I think you misread the issue. I'm not claiming that either the failed installation or the warning message is a bug. See #2119 (comment), from which I borrowed to use as an example of an install that contains a peer dependency incompatibility.

    This issue is entirely about the --force suggestion that npm makes, which as you said is somewhere between misleading and incorrect. The error states: "retry this command with --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution." There's a subject ambiguity here about whether --force will accept the incorrect resolution or whether that only applies to --legacy-peer-deps. But either way that you read this, it suggests that rerunning the command with --force will produce a different output. This isn't true.

    It's not exactly clear to me what the --force modifier actually does on install, but IMO it's not unreasonable to guess that it might mean "ignore peer dependency incompatibilities wrt exit behavior", mirroring the npm@6 behavior. (I know that you hate the thought of this. 🙂) If that's the intention, then there's a bug in the implementation. Or, more likely, this is not the intention in which case it seems that npm shouldn't be making this suggestion at all.

  5. ljharb commented on Nov 5, 2020

    @ljharb
    Contributor

    I don’t think any option should suppress the warnings, but i agree that if the suggestion won’t work, it shouldn’t be phrased as if it will :-)

  6. isaacs commented on Nov 11, 2020

    @isaacs
    Contributor

    Well, yeah, this is a bug. It should either not tell you to use --force or (ideally) --force should provide an override that makes it produce a mostly (but not entirely) correct package tree.

    Rather than roll back to npm v6, I'd suggest using --legacy-peer-deps or putting legacy-peer-deps = true in your project-level .npmrc file. There are a lot of other advantages to using v7.

    Here's the minimal reproduction package.json file that I'm using:

    {
      "devDependencies": {
        "webpack-dev-server": "^3.11.0",
        "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3"
      }
    }
  7. isaacs commented on Nov 11, 2020

    @isaacs
    Contributor

    IMO it's not unreasonable to guess that it might mean "ignore peer dependency incompatibilities wrt exit behavior", mirroring the npm@6 behavior.

    The npm@6 behavior is "ignore peerDependencies entirely". That's what --legacy-peer-deps does.

    --force is either slightly better or much worse in this sort of case. It attempts to infer a reasonable best guess at what version should be placed there, based on prioritizing non-peer dependencies, and failing that, accepting invalid peer deps and moving on.

    You've found a case where we don't do the right thing (or at least, the intended thing, fraught though it may be) in the --force case.

    That bit where it says "recommended protections disabled", this is one of those "recommended protections". npm v7 tries to not ever give you a tree that violates the stated dependency contracts of any packages.

  8. billyjanitsch commented on Nov 11, 2020

    @billyjanitsch
    Author

    --force is either slightly better or much worse in this sort of case. It attempts to infer a reasonable best guess at what version should be placed there, based on prioritizing non-peer dependencies, and failing that, accepting invalid peer deps and moving on.

    Ah, that's what I had originally expected it to do! I like this behavior, because --legacy-peer-deps doesn't work if you've come to rely on npm@7's automatic installation of peer deps for other peer deps, unrelated to the one(s) that are incompatible.

    For example, if you have something like this, where @babel/cli peer-depends on @babel/core:

    {
      "scripts": {
        "build": "babel index.js"
      },
      "devDependencies": {
        "@babel/cli": "^7.12.0",
        "webpack-dev-server": "^3.11.0",
        "webpack": "^5.0.0"
      }
    }

    Using --legacy-peer-deps would ignore the webpack incompatibility, but it would fail to install @babel/core, so npm run build would fail. Whereas, if I understand the intention of --force correctly, it would install @babel/core while also "ignoring" the webpack incompatibility.

    (I understand that this is all danger zone territory, but it does help to understand the intention of --force in the rare case where it's needed. For example: when you're waiting on a third-party package to update a peer dep and you want to test whether it happens to work locally in the meantime. It's nice to have a method to force npm to complete the install rather than bailing from populating node_modules entirely.)

  9. added this to the OSS - Sprint 19 milestone on Nov 16, 2020
  10. bigdaddy3211234 commented on Jun 7, 2021

    @bigdaddy3211234

    Reverting back to npm 6.14.8 solved this for me for now using npm install -g npm@latest

    Super bro.it worked👍

  11. kawcher-habib commented on Apr 6, 2022

    @kawcher-habib

    solved the problem using this command npm install -g npm@latest

    Thank you kapoko

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 stepsRelease 7.xwork is associated with a specific npm 7 release

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions