Visitar URL original
An optional peer stays on its locked version when a sibling dependency is bumped, so `install` and `dedupe` keep two copies · Issue #16443 · pnpm/pnpm · GitHub
Skip to content

An optional peer stays on its locked version when a sibling dependency is bumped, so install and dedupe keep two copies #16443

Closed

Description

@levrik

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

No response

Which area(s) of pnpm are affected? (leave empty if unsure)

Dependencies resolver, Lockfile

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

Verified with pnpm 12.8.2 (Node.js 22.23.1, macOS).

{
  "name": "pnpm-stale-optional-peer",
  "private": true,
  "dependencies": { "vue": "3.5.40" },
  "devDependencies": { "@vue/test-utils": "2.5.1" }
}

@vue/test-utils@2.5.1 declares @vue/compiler-dom, @vue/server-renderer and vue as peers (3.x), with @vue/server-renderer marked optional. vue@3.5.x depends on @vue/server-renderer at its own exact version.

$ pnpm install –lockfile-only
$ grep "^  '@vue/test-utils@2.5.1(" pnpm-lock.yaml
  '@vue/test-utils@2.5.1(@vue/compiler-dom@3.5.40)(@vue/server-renderer@3.5.40)(vue@3.5.40)':

# bump vue to 3.5.43 in package.json
$ pnpm install –lockfile-only
$ pnpm dedupe –lockfile-only
$ grep -E "^  '@vue/(test-utils@2.5.1\(|server-renderer@)" pnpm-lock.yaml
  '@vue/server-renderer@3.5.40':
  '@vue/server-renderer@3.5.43':
  '@vue/test-utils@2.5.1(@vue/compiler-dom@3.5.43)(@vue/server-renderer@3.5.40)(vue@3.5.43)':

Controls, run from the same stale lockfile:

Describe the Bug

After vue goes from 3.5.40 to 3.5.43, the required peer @vue/compiler-dom follows it to 3.5.43. The optional peer @vue/server-renderer stays on 3.5.40, and neither pnpm install nor pnpm dedupe moves it. The lockfile keeps @vue/server-renderer@3.5.40 together with its whole 3.5.40 dependency tree (runtime-dom, runtime-core, reactivity, shared), next to the 3.5.43 copies vue brings in. That happens even though 3.5.43 is already in the graph and satisfies the 3.x peer range.

This caused a real failure for us, not just a bigger lockfile. @vue/test-utils got into a Vite dev build and brought the second Vue runtime with it. Both runtimes register the global __VUE_HMR_RUNTIME__, the stale one registered last, and hot module replacement for Vue components silently stopped working. Nothing hinted at a version mismatch.

This looks like #11800 (fixed in 12.7.0 by #15629), but that fix doesn't cover this case:

  • this is a single project, not a workspace;
  • the stale peer is not recorded under importers:, only inside @vue/test-utils' own peer suffix;
  • no project specifier names @vue/server-renderer. The newer version comes from another package's regular dependency (vue → @vue/server-renderer@3.5.43).

Expected Behavior

When a version that is already in the graph satisfies an optional peer's range, pnpm install (or at least pnpm dedupe) should resolve the peer to it. That's what a fresh install does, and what already happens here for the required peer @vue/compiler-dom.

Which Node.js version are you using?

22.23.1

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

No response

Contributing a fix

  • I am working on a fix

Activity

  1. added theissue type on Sep 30, 2026
  2. altaywtf commented on Sep 30, 2026

    @altaywtf
    Member

    I'm working on a fix for this.

    Written by an agent (Claude Code, claude-opus-5-5).

  3. altaywtf commented on Sep 30, 2026

    @altaywtf
    Member

    A fix is ready for review in #16445. CI is green.

    Written by an agent (Claude Code, claude-opus-5-5).

  4. added a commit that references this issue on Sep 30, 2026
    47d7d3c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions