pnpm ERR_PNPM_LOCKFILE_BREAKING_CHANGE - Fix Incompatible Lockfile Format in CI
pnpm lockfiles carry a format version. ERR_PNPM_LOCKFILE_BREAKING_CHANGE means the committed pnpm-lock.yaml was written by a pnpm major whose lockfile format the pnpm running in CI cannot read.
What this error means
pnpm install (especially with --frozen-lockfile) fails with ERR_PNPM_LOCKFILE_BREAKING_CHANGE, indicating the lockfile format is incompatible with the installed pnpm. Local and CI pnpm versions disagree.
ERR_PNPM_LOCKFILE_BREAKING_CHANGE Lockfile /app/pnpm-lock.yaml
not compatible with current pnpm
The lockfile was created with a newer version of pnpm.Diagnose it: reproduce the CI install locally
Install failures are usually environment drift rather than a broken lockfile: a different package-manager major, a different Node version, or a cache that is being restored from a run with different inputs. Reproduce the CI conditions before changing the lockfile, because regenerating it hides the real cause.
# match the runner exactly, then install from a clean slate
node --version && npm --version
rm -rf node_modules
npm ci --foreground-scripts
# if that succeeds locally but fails in CI, the difference is the cache
# or the package-manager version, not your lockfileCommon causes
CI pnpm is older than the lockfile format
A teammate generated pnpm-lock.yaml with a newer pnpm major (newer lockfile format), but CI runs an older pnpm that cannot parse it.
pnpm version not pinned
Without pinning pnpm (via packageManager or setup), CI and local drift to different majors with incompatible lockfile formats.
How to fix it
Pin pnpm to match the lockfile
Use the same pnpm major everywhere via the packageManager field and Corepack.
// package.json
"packageManager": "pnpm@9.7.0"
# in CI
corepack enable
corepack prepare pnpm@9.7.0 --activate
pnpm install --frozen-lockfileRe-lock if you intend to upgrade
- If you mean to move to a new pnpm major, upgrade pnpm everywhere first.
- Regenerate
pnpm-lock.yamlwith the new pnpm and commit it. - Keep
--frozen-lockfilein CI so drift fails loudly.
Verify the fix survives a cold cache
A green run immediately after a fix often proves nothing, because it restored a cache written before the change. Force a cold install once to confirm the fix is real.
# temporarily bust the cache key to prove the fix on a cold runner
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
# then bump this suffix once, run, and remove it
# key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}-v2How to prevent it
- Pin pnpm via
packageManagerand Corepack. - Upgrade pnpm in lockstep across local and CI.
- Commit the lockfile and use
--frozen-lockfilein CI.