Fix pnpm ERR_PNPM_OUTDATED_LOCKFILE in CI
Find the mismatched workspace importer, align the pnpm version, and prove the repaired lockfile installs without changing a byte.
TL;DR#
ERR_PNPM_OUTDATED_LOCKFILE means a frozen installation needs a lockfile change. Run pnpm install --lockfile-only --no-frozen-lockfile at the project root with the project's intended pnpm version, review the change and commit pnpm-lock.yaml alongside the changed manifests. Then verify with pnpm install --frozen-lockfile. Keep that frozen check in CI; changing the verification job to resolve dependencies on every run hides the drift.
The ordinary manifest mismatch was reproduced on 2 November 2026 in an isolated node:24-slim container running Node 24.22.2 and pnpm 12.16.1. These are selected diagnostic lines from its actual output:
Error: ERR_PNPM_OUTDATED_LOCKFILE
specifiers in the lockfile don't match specifiers in package.json:
* in importers["."]:
* 1 dependency is mismatched:
- is-number (lockfile: 7.0.0, manifest: ^7.0.0)The selected package was still is-number 7.0.0. Only its requested range had changed. That was sufficient to make the CI install exit unsuccessfully.
Why it happens#
The manifest describes what a project requests; the lockfile records the resolved graph and the request specifiers used to create it. A frozen install checks that those inputs agree before accepting the recorded installation. The official error reference identifies a changed manifest or an uncommitted lockfile as common causes.
The install documentation sets the default to false outside CI and true in CI when a lockfile exists. Explicit frozen mode also fails when no lockfile exists. This explains a familiar sequence: a developer edits a dependency, an ordinary local install updates the lockfile, and the developer commits only the manifest. The CI checkout receives the new request with the old resolution record.
A successful application start on the developer's existing dependency tree does not validate the committed lockfile. Nor does a warm package cache: in the reproduction, adding --prefer-offline to the failing CI install produced the same mismatch. Cached tarballs do not change a recorded request specifier.
The historical pnpm issue #5144 contains a more confusing variant: a workspace install printed that the lockfile was current, then rejected a workspace manifest. Its maintainer discussion concerned automatic installation of root peer dependencies. That older bug report is useful evidence of the symptom, but it does not establish that today's manifest drift has the same cause. Start with the dependency and importer named in your current diagnostic.
Fix#
1. Identify the manager that actually runs#
Run these commands from the repository root locally and in the failing job:
node --version
pnpm --version
node -p "require('./package.json').packageManager"Compare the printed version with the repository's intended manager and its CI setup. A floating global installation can change independently of your dependency lockfile. On a POSIX runner, command -v pnpm also shows which executable wins on the command path; on Windows use Get-Command pnpm in PowerShell.
The packageManager documentation describes the exact manager pin. For example, the reproduction used this field:
{
"packageManager": "pnpm@12.16.1"
}This is a manifest fragment to merge into an existing project, not a replacement for its dependencies. Preserve the project's established version while diagnosing an unrelated manifest mismatch. A deliberate manager upgrade deserves its own reviewed lockfile change.
If your environment uses Corepack, its upstream instructions explain how it reads the manager declaration. Inspect both Corepack and the resulting pnpm version; do not assume that every Node image has enabled the same shim. Current pnpm CI guidance recommends its own setup tools instead. Establish which mechanism your job uses before adding a second installer.
If the failure happens earlier, while upgrading npm inside the image, and says EBADENGINE, use the separate Docker npm engine-compatibility diagnosis. A pnpm lockfile update cannot fix an incompatible tool bootstrap.
2. Reconcile the intended manifest and lockfile#
First decide whether the manifest edit belongs in this change. If it was accidental, restore that edit through your normal review workflow. If the new dependency declaration is intentional, keep it and update its lockfile record:
pnpm install --lockfile-only --no-frozen-lockfileRun this at the workspace root when the repository shares a workspace lockfile. According to the lockfile-only option, this updates lockfile and manifest information without installing into the dependency directory. It is useful when the desired change is the resolution record. A later full frozen install must still prove that those dependencies can actually be installed.
The explicit non-frozen option makes this a deliberate update even if your terminal inherits a CI environment. It belongs in the repair operation, followed by review. Removing the lockfile is unnecessary for ordinary request drift and discards the existing resolution you should be checking.
In the reproduction, the repair changed the lockfile's recorded specifier from the exact version to the caret range. The selected dependency version did not change, and no package source or application code was edited. That isolates the cause: the failure was a request mismatch, rather than an unavailable dependency.
3. Review and commit the inputs together#
Inspect the manifest and lockfile changes before staging them:
git diff -- package.json pnpm-lock.yamlFor a workspace, include the changed package manifests and workspace configuration in that review. Investigate unexpected wholesale resolution changes before committing: they can indicate a different pnpm version, changed configuration or an unrelated dependency update.
For a single-package repository, stage the intended pair:
git add package.json pnpm-lock.yaml
git commit -m "Synchronise pnpm lockfile with dependency manifest"Add the actual changed workspace files when applicable. The objective is a commit that contains both the requested dependency state and the resolution that CI will verify. A lockfile repaired only on your workstation cannot change a remote checkout.
If a repair command cannot write the file and reports a permission error, resolve that filesystem problem separately. The npm lockfile EACCES article demonstrates why an existing lockfile can be readable yet unwritable; its npm-specific filename and commands should not be copied blindly into a pnpm project.
Verify the fix#
Run the same frozen mode you expect in the job:
CI=true pnpm install --frozen-lockfileThat environment assignment is POSIX shell syntax. In PowerShell, set the CI environment variable before running the command:
$env:CI = 'true'
pnpm install --frozen-lockfileThe reproduction reran the frozen install after updating the lockfile, compared its bytes with the repaired copy, and checked the installed package at runtime. It also copied only the corrected manifest and lockfile into a fresh directory and ran a frozen install there. Both the existing-tree and clean-directory installations succeeded. The byte comparison printed:
lockfile byte comparison passedThe separate clean-directory runtime check printed:
clean install runtime check passedFor your project, validate from a fresh checkout of the commit being proposed, using the same manager setup as CI. Then run the project's build and tests. An unchanged lockfile plus a successful frozen install demonstrates that pnpm accepted the recorded inputs; application checks demonstrate that the selected dependencies still work for your code.
If a container now starts but reports Cannot find module 'dotenv', investigate Compose mounts hiding installed dependencies. A passing install does not prove that a runtime bind mount exposes the dependency directory installed in the image.
One email a month — the latest explained errors
What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.
Workspace importers and overrides are separate inputs#
In the workspace reproduction, editing only the web package's dependency request caused the diagnostic to identify importers["packages/web"]. Looking exclusively at the root manifest would have missed it. Read the named importer and compare that package's declarations with its lockfile entry.
Next, adding an override to the workspace configuration caused a different failure, despite leaving that package manifest alone:
Error: ERR_PNPM_LOCKFILE_CONFIG_MISMATCHRunning the same deliberate lockfile update and then a frozen install repaired this case too. The configuration mismatch reference distinguishes recorded resolution settings from manifest requests. Review overrides, patches, catalogs and peer-resolution settings when that is the code you receive. A setting mismatch is evidence about configuration, not a reason to edit random dependency versions.
Configuration advice also depends on the manager generation. The pnpm 10 settings reference describes the older configuration surface, whereas current configuration guidance puts non-authentication settings in the workspace YAML and no longer reads general pnpm settings from the manifest's pnpm field. In addition, current manager-selection settings use pmOnFail in place of older manager strictness and switching controls. Check the documentation matching the version you actually run before copying an old configuration workaround.
A manager upgrade can change the lockfile itself#
Current pnpm can write a separate boot document containing configuration dependencies and the resolved manager pin before the project's dependency graph. The lockfile format documentation explains that both documents can share the same schema version. A familiar schema header therefore does not prove that an older pnpm or a single-document YAML tool understands the complete file.
Changing the pinned manager without updating that boot document can produce ERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE. Follow that diagnostic: generate the lockfile with the intended manager and commit the result. Do not hand-edit its schema header to make another version accept it. The CI documentation also says incompatible lockfiles fail in CI rather than being silently rewritten.
Keep the troubleshooting sequence narrow: identify the actual pnpm version, inspect the importer or configuration named by the error, make the intentional lockfile update, and verify the committed result with frozen installation. A repeatable CI build starts with those inputs agreeing.
Further reading: Fix pnpm ERR_PNPM_LINKING_FAILED on Windows.
Frequently Asked Questions
Still stuck? Paste your error.
Paste the error message or stack trace — we check it against every fix and tool on the site.
Continue Reading
Fix pnpm ERR_PNPM_LINKING_FAILED on Windows
Find the process or path preventing a pnpm rename, distinguish a locked package from a version regression, and retain the dependency resolution.
Fix pnpm Ignored Build Scripts for Native Dependencies
Reproduce a missing SQLite binding, approve only its installer, and keep the same permission working in CI without enabling every dependency script.
Fix npm ERR! Unexpected token '.' with nvm-windows
How to confirm the broken libnpmfund file in under a minute, why only npm 8.3.1 and later trip on it, and the reinstall that actually repairs the Node version you already have.


