Skip to content

fix: Preserve dedupePeers and unknown pnpm lockfile settings#12443

Merged
anthonyshew merged 2 commits intovercel:mainfrom
attehuhtakangas:fix/pnpm-lockfile-settings-dedupe-peers
Mar 25, 2026
Merged

fix: Preserve dedupePeers and unknown pnpm lockfile settings#12443
anthonyshew merged 2 commits intovercel:mainfrom
attehuhtakangas:fix/pnpm-lockfile-settings-dedupe-peers

Conversation

@attehuhtakangas
Copy link
Copy Markdown
Contributor

Summary

turbo prune --docker silently drops unknown fields from the settings block in pnpm-lock.yaml. pnpm 10.33.0 added dedupePeers to the lockfile settings, and after pruning this field is lost, causing pnpm install --frozen-lockfile to fail with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH.

Changes

  1. Added dedupe_peers and peers_suffix_max_length fields to LockfileSettings in crates/turborepo-lockfiles/src/pnpm/data.rs
  2. Added #[serde(flatten)] catch-all map to LockfileSettings for forward-compatibility with any future pnpm settings (matching the existing pattern used by PackageSnapshot)
  3. Added two tests:
    • test_lockfile_settings_preserve_dedupe_peers -- verifies dedupePeers survives a prune round-trip
    • test_lockfile_settings_preserve_unknown_fields -- verifies arbitrary future settings survive a round-trip via the catch-all

Root cause

The LockfileSettings struct only had auto_install_peers, exclude_links_from_lockfile, and inject_workspace_packages. Without #[serde(deny_unknown_fields)] or #[serde(flatten)], serde silently drops unknown YAML keys during deserialization. When the lockfile is re-serialized after pruning, the missing settings cause pnpm to detect a config mismatch.

Prior art

Fixes #12442

pnpm 10.33.0 added `dedupePeers` to the lockfile settings block.
The `LockfileSettings` struct was missing this field (and
`peersSuffixMaxLength`), causing them to be silently dropped during
deserialization. After `turbo prune --docker`, the pruned lockfile
was missing these settings, which made `pnpm install --frozen-lockfile`
fail with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`.

This commit:
1. Adds explicit `dedupe_peers` and `peers_suffix_max_length` fields
2. Adds a `#[serde(flatten)]` catch-all map (matching the existing
   pattern in `PackageSnapshot`) so any future pnpm settings are
   preserved through round-trips
3. Adds tests for both the specific field and the generic catch-all

Fixes vercel#12442
@attehuhtakangas attehuhtakangas requested a review from a team as a code owner March 24, 2026 21:19
@attehuhtakangas attehuhtakangas requested review from tknickman and removed request for a team March 24, 2026 21:19
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 24, 2026

@attehuhtakangas is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@anthonyshew anthonyshew changed the title fix(lockfiles): preserve dedupePeers and unknown pnpm lockfile settings fix: Preserve dedupePeers and unknown pnpm lockfile settings Mar 25, 2026
Copy link
Copy Markdown
Contributor

@anthonyshew anthonyshew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for this addition.

I've removed the catch-all behavior because we always want to make sure we handle any configurations that folks are using. It's easier for us to handle and make sure we handle a set of known keys rather than allow for any unknown behaviors.

@anthonyshew anthonyshew enabled auto-merge (squash) March 25, 2026 16:56
@anthonyshew anthonyshew merged commit 1529b92 into vercel:main Mar 25, 2026
46 of 57 checks passed
github-actions Bot added a commit that referenced this pull request Mar 25, 2026
## Release v2.8.21-canary.10

Versioned docs: https://v2-8-21-canary-10.turborepo.dev

### Changes

- release(turborepo): 2.8.21-canary.9 (#12432) (`2e2f8c3`)
- fix: Use script-shell=bash for cross-platform with-shell-commands
example (#12436) (`d5c2192`)
- docs: Add AI guide to sidebar navigation (#12438) (`021d288`)
- docs: Move `experimentalObservability` into `futureFlags` section
(#12439) (`85812cc`)
- fix: Skip Unix domain sockets and other special files during file
hashing (#12445) (`eb8f75e`)
- fix: Preserve dedupePeers and unknown pnpm lockfile settings (#12443)
(`1529b92`)

Co-authored-by: Turbobot <turbobot@vercel.com>
github-actions Bot added a commit that referenced this pull request Mar 28, 2026
## Release v2.8.21

Versioned docs: https://v2-8-21.turborepo.dev

### Changes

- release(turborepo): 2.8.20 (#12396) (`45230ec`)
- fix: Disable husky hooks in `update-examples` workflow (#12397)
(`56b79ff`)
- docs: Add link to Docker guide in prune --docker flag section (#12401)
(`e7f0db7`)
- feat: Add `global` configuration key behind
`futureFlags.globalConfiguration` (#12399) (`5f190cf`)
- chore: Update CODEOWNERS to remove /docs owner (#12402) (`3233d3a`)
- fix: Strip JSX components from heading anchors and TOC entries
(#12404) (`3abe553`)
- fix: Move docs app icons into app/ directory (#12403) (`ddf3918`)
- feat: Add experimental structured logging with `--json` and
`--log-file` flags (#12405) (`7ca0601`)
- release(turborepo): 2.8.21-canary.1 (#12407) (`adebb95`)
- docs: Downgrade Next.js (#12408) (`281e89b`)
- chore: Deprecate the `turbo scan` command (#12406) (`4a12c26`)
- release(turborepo): 2.8.21-canary.2 (#12409) (`b9ef212`)
- fix(eslint-plugin-turbo): Guard against missing tasks/pipeline in
forEachTaskDef (#12411) (`6c107c2`)
- release(turborepo): 2.8.21-canary.3 (#12413) (`a2e6635`)
- chore: Upgrade Next.js (#12415) (`b9e6174`)
- Revert "fix: Flush stale mouse tracking events from stdin during TUI
cleanup" (#12416) (`646b06e`)
- fix: Add NixOS environment variables to default passthroughs (#12417)
(`4f12c69`)
- release(turborepo): 2.8.21-canary.4 (#12419) (`19cb539`)
- fix: Resolve security vulnerabilities in `tar` and `rustls-webpki`
(#12418) (`f09b138`)
- release(turborepo): 2.8.21-canary.5 (#12420) (`8aca047`)
- docs: Promote `turbo query` from experimental to stable (#12421)
(`0692aba`)
- docs: Clarify `turbo-ignore`'s future (#12422) (`c5a8235`)
- release(turborepo): 2.8.21-canary.6 (#12423) (`3ebf536`)
- feat: Rework turbo ls to use query internals and add turbo query ls
shorthand (#12424) (`84fd6e3`)
- docs: Clarify environment variables across packages dependency
behavior (#12390) (`e44b0d8`)
- docs: Expand subpath imports example (#12412) (`a7fec57`)
- fix(examples): Update of `with-svelte` example (#11952) (`41d1b2e`)
- release(turborepo): 2.8.21-canary.7 (#12425) (`7155a67`)
- fix: Preserve source dependencies when adding workspace deps in
`turbo-gen` (#11935) (`01c56cc`)
- docs: Add Git history requirements to `turbo query affected` docs
(#12426) (`edc16d5`)
- fix: Prevent horizontal overflow from long inline code on narrow
viewports (#12428) (`a5d641b`)
- release(turborepo): 2.8.21-canary.8 (#12429) (`46814d0`)
- feat: Send git SHA and dirty hash to remote cache (#12427) (`192034a`)
- fix: Upgrade tokio to 1.47.1+ to fix pidfd_reaper panic (#12431)
(`8c25d47`)
- release(turborepo): 2.8.21-canary.9 (#12432) (`2e2f8c3`)
- fix: Use script-shell=bash for cross-platform with-shell-commands
example (#12436) (`d5c2192`)
- docs: Add AI guide to sidebar navigation (#12438) (`021d288`)
- docs: Move `experimentalObservability` into `futureFlags` section
(#12439) (`85812cc`)
- fix: Skip Unix domain sockets and other special files during file
hashing (#12445) (`eb8f75e`)
- fix: Preserve dedupePeers and unknown pnpm lockfile settings (#12443)
(`1529b92`)
- release(turborepo): 2.8.21-canary.10 (#12446) (`014111c`)
- fix: Align dry run cache status with normal run by checking caching
guards (#12448) (`48aa171`)
- release(turborepo): 2.8.21-canary.11 (#12450) (`b14aa0b`)
- fix: Resolve turbo watch hang with mixed interruptible persistent
tasks (#12449) (`326532d`)
- release(turborepo): 2.8.21-canary.12 (#12451) (`379d47b`)
- fix: Avoid `setsid()` in PTY spawn to prevent macOS Gatekeeper CPU
spikes (#12452) (`dcc9f6a`)
- release(turborepo): 2.8.21-canary.13 (#12453) (`19f46e6`)
- feat: Add `packagesFromLockfile()` NAPI binding to `@turbo/repository`
(#12454) (`c58ee79`)
- release(library): 0.0.1-canary.21 (#12455) (`3637185`)
- release(turborepo): 2.8.21-canary.14 (#12456) (`3f87769`)
- refactor: Move cache hit SHA context to verbose logging (#12435)
(`23c15b4`)
- release(turborepo): 2.8.21-canary.15 (#12457) (`6353482`)
- docs: Add missing --force flag documentation (#12440) (`e3b89b0`)
- fix: Prevent panic in turbo watch with persistent tasks (#12459)
(`337b2e8`)
- release(turborepo): 2.8.21-canary.16 (#12461) (`e79a56b`)
- fix: Support `turbo watch` in single-package workspaces (#12460)
(`ae78ce1`)
- release(turborepo): 2.8.21-canary.17 (#12463) (`0bafae2`)
- fix: Missing deps after npm lockfile parsing (#12464) (`fe5a86e`)
- release(turborepo): 2.8.21-canary.18 (#12465) (`c014134`)
- docs: Add AI agent detection and automatic markdown rewrites (#12462)
(`50bd872`)
- fix: Resolve generator name conflicts across workspaces (#12467)
(`d5d37a8`)
- release(turborepo): 2.8.21-canary.19 (#12468) (`7552e93`)
- fix: Remove root package.json from `--affected` global triggers
(#12469) (`91ebb97`)
- release(turborepo): 2.8.21-canary.20 (#12470) (`c5a4690`)
- fix: Show run summary after TUI exits (#12471) (`ffa47d1`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

turbo prune drops unknown pnpm lockfile settings (dedupePeers)

2 participants