fix: throw a frozen lockfile error when catalogs change#10231
Conversation
``` > @ step1 /home/runner/work/pnpm/pnpm/__fixtures__ > node ../pnpm/dist/pnpm.mjs install -rf --frozen-lockfile --no-shared-workspace-lockfile --no-link-workspace-packages . | WARN using --force I sure hope you know what you are doing Scope: all 26 workspace projects circular | Progress: resolved 1, reused 0, downloaded 0, added 0 circular | +4 + fixture | Progress: resolved 1, reused 0, downloaded 0, added 0 fixture | +12 + fixture-with-no-pkg-name-and-no-version | Progress: resolved 1, reused 0, downloaded 0, added 0 fixture-with-no-pkg-name-and-no-version | +12 + fixture-with-no-pkg-version | Progress: resolved 1, reused 0, downloaded 0, added 0 fixture-with-no-pkg-version | +12 + circular | Progress: resolved 4, reused 0, downloaded 4, added 4, done fixture | Progress: resolved 12, reused 6, downloaded 6, added 12, done fixture-with-no-pkg-name-and-no-version | Progress: resolved 12, reused 0, downloaded 0, added 12, done fixture-with-no-pkg-version | Progress: resolved 12, reused 0, downloaded 0, added 12, done general | Progress: resolved 1, reused 0, downloaded 0, added 0 general | +13 + has-2-outdated-deps | Progress: resolved 1, reused 0, downloaded 0, added 0 has-2-outdated-deps | +2 + undefined /home/runner/work/pnpm/pnpm/__fixtures__/has-outdated-deps-using-catalog-protocol: ERR_PNPM_LOCKFILE_CONFIG_MISMATCH Cannot proceed with the frozen installation. The current "catalogs" configuration doesn't match the value found in the lockfile Update your lockfile using "pnpm install --no-frozen-lockfile" ```
bf4e9ef to
f4a77be
Compare
| catalog: | ||
| # Used in has-outdated-deps-using-catalog-protocol fixture. | ||
| is-negative: ^1.0.0 |
There was a problem hiding this comment.
This had to be added since we're installing the has-outdated-deps-using-catalog-protocol fixture's dependencies using this pnpm-workspace.yaml on CI.
pnpm/__fixtures__/package.yaml
Line 2 in ad0cfad
The bug fix revealed a place we were accidentally relying on the old (buggy) behavior.
| if (!opts.ignorePackageManifest) { | ||
| const outdatedLockfileSettingName = getOutdatedLockfileSetting(ctx.wantedLockfile, { | ||
| autoInstallPeers: opts.autoInstallPeers, | ||
| catalogs: opts.catalogs, |
There was a problem hiding this comment.
Is it correct to model catalogs here as a "lockfile setting"? I think it's technically something different. I can inline the allCatalogsAreUpToDate check here and throw a more custom error if that's preferred.
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug where pnpm failed to throw a frozen lockfile error when catalog configurations changed in pnpm-workspace.yaml during a pnpm install --frozen-lockfile command. The fix adds catalog validation to the lockfile settings checker, ensuring catalogs are treated similarly to other configuration settings like overrides.
Key Changes
- Added
catalogsparameter togetOutdatedLockfileSettingfunction to validate catalog configurations - Integrated
allCatalogsAreUpToDatefunction from@pnpm/lockfile.verificationto check if catalog snapshots match current config - Updated all call sites to pass the
catalogsparameter when checking for outdated lockfile settings
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
lockfile/settings-checker/src/getOutdatedLockfileSetting.ts |
Added catalogs parameter and validation check using allCatalogsAreUpToDate |
lockfile/settings-checker/package.json |
Added dependencies for @pnpm/catalogs.types and @pnpm/lockfile.verification |
lockfile/settings-checker/tsconfig.json |
Added project references for new dependencies |
lockfile/verification/src/index.ts |
Exported allCatalogsAreUpToDate function |
pkg-manager/core/src/install/index.ts |
Passed catalogs parameter to getOutdatedLockfileSetting |
deps/status/src/checkDepsStatus.ts |
Passed catalogs parameter to getOutdatedLockfileSetting |
pkg-manager/core/test/catalogs.ts |
Added test verifying frozen lockfile error is thrown when catalog config changes |
pnpm-lock.yaml |
Updated lockfile with new dependencies |
__fixtures__/pnpm-workspace.yaml |
Added catalog fixture for testing |
.changeset/salty-beds-sell.md |
Documented the fix with appropriate package versions |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for reviewing! |
…lify (#9364) ## Summary Pin `packageManager` back to `[email protected]` to unblock Netlify docs deploys. ## Context After #9347 bumped pnpm `10.23.0` → `10.33.4`, every Netlify deploy started failing during `pnpm install` with: ``` ERR_PNPM_LOCKFILE_CONFIG_MISMATCH Cannot proceed with the frozen installation. The current "catalogs" configuration doesn't match the value found in the lockfile Update your lockfile using "pnpm install --no-frozen-lockfile" ``` Root cause: pnpm **10.24.0** added a strict catalog comparison for `--frozen-lockfile` mode via [pnpm/pnpm#10231](pnpm/pnpm#10231). The comparison logic (`allCatalogsAreUpToDate`) is buggy — it reports a mismatch even though the workspace catalog and lockfile snapshot are identical, and `pnpm install --no-frozen-lockfile` locally produces zero diff. This is the same issue [sapphi-red](https://github.com/sapphi-red) already filed against pnpm using this repo as the reproduction: [pnpm/pnpm#10258](pnpm/pnpm#10258) (still open, no comments from maintainers). `#9343` (the npm packages renovate PR that changed `valibot` and `vitepress-plugin-graphviz` in the catalog) only made the failure visible — the regression was introduced by the pnpm bump.
…lify (#9364) ## Summary Pin `packageManager` back to `[email protected]` to unblock Netlify docs deploys. ## Context After #9347 bumped pnpm `10.23.0` → `10.33.4`, every Netlify deploy started failing during `pnpm install` with: ``` ERR_PNPM_LOCKFILE_CONFIG_MISMATCH Cannot proceed with the frozen installation. The current "catalogs" configuration doesn't match the value found in the lockfile Update your lockfile using "pnpm install --no-frozen-lockfile" ``` Root cause: pnpm **10.24.0** added a strict catalog comparison for `--frozen-lockfile` mode via [pnpm/pnpm#10231](pnpm/pnpm#10231). The comparison logic (`allCatalogsAreUpToDate`) is buggy — it reports a mismatch even though the workspace catalog and lockfile snapshot are identical, and `pnpm install --no-frozen-lockfile` locally produces zero diff. This is the same issue [sapphi-red](https://github.com/sapphi-red) already filed against pnpm using this repo as the reproduction: [pnpm/pnpm#10258](pnpm/pnpm#10258) (still open, no comments from maintainers). `#9343` (the npm packages renovate PR that changed `valibot` and `vitepress-plugin-graphviz` in the catalog) only made the failure visible — the regression was introduced by the pnpm bump.
…atch bug (#9471) ## Summary - Adds `PNPM_FLAGS = "--no-frozen-lockfile"` to `docs/netlify.toml` `[build.environment]`. - Works around [pnpm/pnpm#10258](pnpm/pnpm#10258) — pnpm >=10.24 (incl. 11.x) spuriously throws `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` on Netlify under `--frozen-lockfile`, even when the workspace catalog and lockfile snapshot are byte-for-byte equivalent. ## Context #9447 bumped `packageManager` from `[email protected]` → `[email protected]` and removed the pin from #9364. pnpm 11.x carries the same buggy `allCatalogsAreUpToDate` check introduced in pnpm 10.24.0 ([pnpm/pnpm#10231](pnpm/pnpm#10231)), so Netlify deploys started failing again with the same false-positive catalog mismatch. I confirmed locally that `pnpm install --frozen-lockfile` on this commit with pnpm 11.1.2 + Node 24.12.0 succeeds clean — the bug only fires inside Netlify's build sandbox. The upstream issue is still open with no maintainer activity and this repo as the reproduction. ## Approach The failure occurs in Netlify's **pre-install stage** (before the project's build `command` runs), so any flag we put inside the build command is too late. Netlify forwards `PNPM_FLAGS` directly to that pre-install `pnpm install` invocation, so setting `PNPM_FLAGS = "--no-frozen-lockfile"` is enough to skip the buggy guard at the right step. Earlier attempts to disable frozen mode via `NPM_CONFIG_FROZEN_LOCKFILE` / `PNPM_CONFIG_FROZEN_LOCKFILE` and to pin the workspace root via `NPM_CONFIG_WORKSPACE_DIR` were dropped — they either weren't honored by pnpm 11 (the v11 migration changed which prefixes settings are read from) or didn't address the pre-install stage at all. `PNPM_FLAGS` is Netlify's intended hook for this and turns out to be the minimal fix. Scope is intentionally narrow: - Only the Netlify env gets the flag (via `docs/netlify.toml`, not `.npmrc`). - GitHub Actions CI keeps frozen-lockfile, so genuine drift is still caught upstream. - `packageManager` stays on pnpm 11.1.2 — no rollback of #9447. - The docs build `command` is unchanged; Netlify's own pre-install handles dependencies and the `--no-frozen-lockfile` flag rides along through `PNPM_FLAGS`. --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: shulaoda <[email protected]>
…atch bug (rolldown#9471) ## Summary - Adds `PNPM_FLAGS = "--no-frozen-lockfile"` to `docs/netlify.toml` `[build.environment]`. - Works around [pnpm/pnpm#10258](pnpm/pnpm#10258) — pnpm >=10.24 (incl. 11.x) spuriously throws `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` on Netlify under `--frozen-lockfile`, even when the workspace catalog and lockfile snapshot are byte-for-byte equivalent. ## Context rolldown#9447 bumped `packageManager` from `[email protected]` → `[email protected]` and removed the pin from rolldown#9364. pnpm 11.x carries the same buggy `allCatalogsAreUpToDate` check introduced in pnpm 10.24.0 ([pnpm/pnpm#10231](pnpm/pnpm#10231)), so Netlify deploys started failing again with the same false-positive catalog mismatch. I confirmed locally that `pnpm install --frozen-lockfile` on this commit with pnpm 11.1.2 + Node 24.12.0 succeeds clean — the bug only fires inside Netlify's build sandbox. The upstream issue is still open with no maintainer activity and this repo as the reproduction. ## Approach The failure occurs in Netlify's **pre-install stage** (before the project's build `command` runs), so any flag we put inside the build command is too late. Netlify forwards `PNPM_FLAGS` directly to that pre-install `pnpm install` invocation, so setting `PNPM_FLAGS = "--no-frozen-lockfile"` is enough to skip the buggy guard at the right step. Earlier attempts to disable frozen mode via `NPM_CONFIG_FROZEN_LOCKFILE` / `PNPM_CONFIG_FROZEN_LOCKFILE` and to pin the workspace root via `NPM_CONFIG_WORKSPACE_DIR` were dropped — they either weren't honored by pnpm 11 (the v11 migration changed which prefixes settings are read from) or didn't address the pre-install stage at all. `PNPM_FLAGS` is Netlify's intended hook for this and turns out to be the minimal fix. Scope is intentionally narrow: - Only the Netlify env gets the flag (via `docs/netlify.toml`, not `.npmrc`). - GitHub Actions CI keeps frozen-lockfile, so genuine drift is still caught upstream. - `packageManager` stays on pnpm 11.1.2 — no rollback of rolldown#9447. - The docs build `command` is unchanged; Netlify's own pre-install handles dependencies and the `--no-frozen-lockfile` flag rides along through `PNPM_FLAGS`. --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: shulaoda <[email protected]>
Changes
Fixes:
Before
After