Skip to content

Shared peer still resolved inconsistently after #12081 when the consumer is a grandchild of the shadow #12098

Description

@andersk

Last pnpm version that worked

9.8.0

pnpm version

11.5.0 (and main 54d2b57; not fixed by #12081)

Code to reproduce the issue

mkdir parser plugin wrapper shadow
>parser/package.json echo '{"name": "parser", "version": "0.0.0", "peerDependencies": {"typescript": "*"}}'
>plugin/package.json echo '{"name": "plugin", "version": "0.0.0", "peerDependencies": {"typescript": "*", "parser": "file:../parser"}}'
>wrapper/package.json echo '{"name": "wrapper", "version": "0.0.0", "dependencies": {"plugin": "file:../plugin"}}'
>shadow/package.json echo '{"name": "shadow", "version": "0.0.0", "dependencies": {"typescript": "^5", "parser": "file:../parser", "wrapper": "file:../wrapper"}}'
>package.json echo '{"name": "app", "version": "0.0.0", "dependencies": {"typescript": "^6", "parser": "file:parser", "shadow": "file:shadow"}}'
pnpm install
jq .version node_modules/shadow/../wrapper/../plugin/../typescript/package.json
jq .version node_modules/shadow/../wrapper/../plugin/../parser/../typescript/package.json

Expected behavior

"5.9.3"
"5.9.3"

As in #12079, plugin peer-depends typescript, and it also peer-depends parser which peer-depends typescript, so these are expected to resolve to the same version of typescript. This was the behavior of pnpm 9.8.0 and earlier.

Actual behavior

"5.9.3"
"6.0.3"

As in #12079, two incompatible versions of typescript are both visible to plugin via peer-dependency chains.

Additional information

flowchart
  root --> ts6["typescript@^6"]
  root --> parser
  root --> shadow
  shadow --> ts5["typescript@^5"]
  shadow --> parser
  shadow --> wrapper
  wrapper --> plugin
  parser -. peer-depends .-> typescript
  plugin -. peer-depends .-> typescript
  plugin -. peer-depends .-> parser
Loading

The merged patch #12081 only narrowly matches the scenario from #12079, and is fooled here by replacing the direct dependency shadowplugin with a transitive dependency shadowwrapperplugin. A more principled solution is needed that fully addresses the algorithmic problem rather than narrowly matching a specific problematic scenario.

(Another scenario that remains problematic is when instead the direct peer-dependency plugintypescript is replaced by a second transitive peer-dependency path pluginwrappertypescript.)

Node.js version

24.15.0

Operating System

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions