[BUG] ERESOLVE on in-place update: conflict from an optional peer that never gets installed
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.1k
- Forks
- 4.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 19
Description
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
Bumping one dev dependency by a single patch version fails with ERESOLVE. The conflict npm reports comes from a package it never installs.
Going from @vitejs/plugin-react@6.0.3 to 6.0.4 against an existing lockfile:
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: eresolve-repro@1.0.0
npm error Found: @vitejs/plugin-react@6.0.3
npm error node_modules/@vitejs/plugin-react
npm error dev @vitejs/plugin-react@"6.0.4" from the root project
npm error
npm error Could not resolve dependency:
npm error dev @vitejs/plugin-react@"6.0.4" from the root project
npm error
npm error Conflicting peer dependency: @babel/core@8.0.1
npm error node_modules/@babel/core
npm error peer @babel/core@"^8.0.0" from @babel/plugin-transform-runtime@8.0.1
npm error node_modules/@babel/plugin-transform-runtime
npm error peerOptional @babel/plugin-transform-runtime@"^7.29.0 || ^8.0.0-rc.1" from @rolldown/plugin-babel@0.2.3
npm error node_modules/@rolldown/plugin-babel
npm error peerOptional @rolldown/plugin-babel@"^0.1.7 || ^0.2.0" from @vitejs/plugin-react@6.0.4
npm error node_modules/@vitejs/plugin-react
npm error dev @vitejs/plugin-react@"6.0.4" from the root project
It gets there through two levels of optional peers:
@vitejs/plugin-react -> peerOptional @rolldown/plugin-babel -> peerOptional @babel/plugin-transform-runtime -> peer @babel/core@^8
and that last one collides with the @babel/core@7.29.7 already in the tree.
@rolldown/plugin-babel is not in the lockfile before the update, and it's not there after a clean install of the updated package.json either. npm is right not to install it. It still fails the install over a conflict that only that package would have caused.
I think this is the same bug as #8416, just a smaller case. The repros on that thread all involve real version conflicts between packages that do get installed. Here nothing conflicting ends up in the tree in any working state.
Expected Behavior
Step 2 below should resolve. Step 3 shows the end state is fine: same package.json, no lockfile, installs without complaint, no @rolldown/plugin-babel anywhere, @babel/core still 7.29.7.
An optional peer that can't be satisfied should get skipped, the way it already is on a clean install.
Steps To Reproduce
-
In an empty directory, create this
package.json:{ "name": "eresolve-repro", "version": "1.0.0", "devDependencies": { "@vitejs/plugin-react": "6.0.3", "workbox-build": "7.3.0" } } -
Install the baseline. Works:
npm install -
Bump the one dev dependency and reinstall. Fails with
ERESOLVE:npm pkg set devDependencies.@vitejs/plugin-react=6.0.4 npm install -
Drop the lockfile and install the same
package.json. Works:rm -rf package-lock.json node_modules npm install -
Check that the package from the error message isn't actually there:
npm ls @rolldown/plugin-babel # └── (empty) npm ls @babel/core # only 7.29.7, under workbox-build
Some other things I checked:
- Same result on npm 10.9.4, 11.16.0 and 12.0.1.
vite-plugin-pwa@1.3.0works in place ofworkbox-build@7.3.0(it depends on workbox-build). That's how I ran into this, on a Vite PWA app whose automated dependency PR broke.workbox-builddoesn't reduce any further.@babel/core@7.29.7on its own doesn't trigger it, and neither does adding@babel/preset-envor@rollup/plugin-babel, so it looks like it needs the whole Babel 7 tree workbox-build pulls in.- Nothing changed in the package being bumped.
@vitejs/plugin-react6.0.3 and 6.0.4 declare identicalpeerDependenciesandpeerDependenciesMeta. What changed upstream is@babel/plugin-transform-runtime@8.0.1, published 2026-06-17, landing inside the existing^7.29.0 || ^8.0.0-rc.1range.
Impact: this breaks update bots. Renovate reports Artifact file update failure and opens the PR with package.json bumped but the lockfile untouched, so CI then dies at npm ci on the mismatch. Fixing it by hand means regenerating the whole lockfile, which drags in unrelated transitive bumps the bot never meant to make.
Workarounds:
- delete
package-lock.jsonand reinstall --legacy-peer-deps"overrides": { "@babel/plugin-transform-runtime": "^7.29.0" }
Possibly related:
- #8416, same bug as far as I can tell, with larger repros
- #9324, same "clean install works, in-place update doesn't" symptom, but that one is about genuine conflicts between packages that do get installed
Environment
- npm: 11.16.0
- Node.js: 24.18.0
- OS Name: macOS 15.7.7
- System Model Name: Macbook Pro
- npm config:
; "user" config from /Users/user/.npmrc
//npm.pkg.github.com/:_authToken = (protected)
; node bin location = /Users/user/.nvm/versions/node/v24.18.0/bin/node
; node version = v24.18.0
; npm local prefix = /private/tmp
; npm version = 11.16.0
; cwd = /private/tmp
; HOME = /Users/user
; Run `npm config ls -l` to show all defaults.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the package.json and npm install commands in the report, comparing the in-place update with the clean install after removing package-lock.json and node_modules. Trace how the resolver handles the two levels of optional peers and the existing @babel/core@7.29.7. Done means the update resolves without installing @rolldown/plugin-babel or reporting a conflict, while the clean-install result remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nodejs
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100