Verify canary release
Link to code that reproduces this issue
https://github.com/Eyalm321/turbo-12824-repro
Which canary version will you have in your reproduction?
2.9.15-canary.3
Environment information
CLI:
Version: 2.9.15-canary.3
Package manager: pnpm9 # turbo's bucket for pnpm >= 9 (detect_pnpm6_or_pnpm in pnpm.rs); real binary below
Platform:
Architecture: x86_64
Operating system: linux
Node.js version: v24.15.0
pnpm binary: 10.10.0 # reproduces on current pnpm; pnpm-side companion: pnpm/pnpm#11662
Expected behavior
turbo prune my-app --docker produces an out/pnpm-lock.yaml that pnpm install --frozen-lockfile can install without error.
Actual behavior
pnpm install --frozen-lockfile on the pruned lockfile crashes:
ERROR Cannot use 'in' operator to search for 'directory' in undefined
at lockfileToDepGraph
at headlessInstall
at async tryFrozenInstall
The pruned out/pnpm-lock.yaml is missing the base @repo/shared@file:packages/shared entry under packages:, while still listing the @repo/shared@file:packages/shared(react@17.0.2) variant under snapshots:. The variant inherits its resolution from the base entry, so once the base entry is gone pnpm reads resolution: undefined and crashes.
pnpm install --frozen-lockfile on the original (pre-prune) lockfile succeeds — only the pruned output crashes, which isolates the fault to turbo prune.
To Reproduce
git clone https://github.com/Eyalm321/turbo-12824-repro
cd turbo-12824-repro
pnpm install --frozen-lockfile
pnpm exec turbo prune my-app --docker
mkdir -p /tmp/layer
cp -r out/json/. /tmp/layer/
cp out/pnpm-lock.yaml /tmp/layer/pnpm-lock.yaml
cd /tmp/layer
pnpm install --frozen-lockfile # crashes here
Run on Linux/macOS — turbo prune needs symlink support.
Additional context
A single consumer does not reproduce. pnpm only emits the injected file: peer-variant when the peer resolves per-consumer, so the repro has two apps (my-app, app2) pinning different react versions with injectWorkspacePackages: true + dependenciesMeta.injected.
PnpmLockfile::subgraph in crates/turborepo-lockfiles/src/pnpm/data.rs retains the variant key, but get_packages(&variant_key) returns None (pnpm keys packages: without the peer suffix), so the base entry holding the directory resolution is dropped.
Verify canary release
Link to code that reproduces this issue
https://github.com/Eyalm321/turbo-12824-repro
Which canary version will you have in your reproduction?
2.9.15-canary.3
Environment information
Expected behavior
turbo prune my-app --dockerproduces anout/pnpm-lock.yamlthatpnpm install --frozen-lockfilecan install without error.Actual behavior
pnpm install --frozen-lockfileon the pruned lockfile crashes:The pruned
out/pnpm-lock.yamlis missing the base@repo/shared@file:packages/sharedentry underpackages:, while still listing the@repo/shared@file:packages/shared(react@17.0.2)variant undersnapshots:. The variant inherits itsresolutionfrom the base entry, so once the base entry is gone pnpm readsresolution: undefinedand crashes.pnpm install --frozen-lockfileon the original (pre-prune) lockfile succeeds — only the pruned output crashes, which isolates the fault toturbo prune.To Reproduce
Run on Linux/macOS —
turbo pruneneeds symlink support.Additional context
A single consumer does not reproduce. pnpm only emits the injected
file:peer-variant when the peer resolves per-consumer, so the repro has two apps (my-app,app2) pinning differentreactversions withinjectWorkspacePackages: true+dependenciesMeta.injected.PnpmLockfile::subgraphincrates/turborepo-lockfiles/src/pnpm/data.rsretains the variant key, butget_packages(&variant_key)returnsNone(pnpm keyspackages:without the peer suffix), so the base entry holding thedirectoryresolution is dropped.