Skip to content
Latchkey

pnpm "ERR_PNPM_UNEXPECTED_STORE" - Fix Store Path Mismatch in CI

pnpm links node_modules from a content-addressable store and records which store path it used. ERR_PNPM_UNEXPECTED_STORE means the existing node_modules was built against a different store than the one pnpm now resolves - usually a cache or path change between runs.

What this error means

pnpm install aborts with ERR_PNPM_UNEXPECTED_STORE, reporting that node_modules was created with a different store location. It commonly appears when a restored node_modules cache came from a runner with a different store path.

pnpm output
ERR_PNPM_UNEXPECTED_STORE  Unexpected store location
The node_modules was created using a different store path.
Current store: /home/runner/.pnpm-store/v3
Expected store: /root/.pnpm-store/v3

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.

Terminal
# 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 lockfile

Common causes

node_modules restored from a different store path

A cached node_modules built where the pnpm store sat at one path is restored on a runner whose store path differs (different HOME/user), so the recorded store no longer matches.

The store path changed between runs

Changing store-dir, the HOME directory, or the user between runs moves the store, invalidating the link metadata in an existing node_modules.

How to fix it

Reset node_modules and pin the store path

Remove the mismatched node_modules and set a stable store directory.

Terminal
rm -rf node_modules
pnpm config set store-dir ~/.pnpm-store
pnpm install

Cache the store, not node_modules

  1. Cache the pnpm store directory keyed on the lockfile, and let pnpm relink node_modules each run.
  2. Set a fixed store-dir so its path does not vary by user/HOME.
  3. Avoid restoring a node_modules built on a differently-pathed store.

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.

.github/workflows/ci.yml
# 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') }}-v2

How to prevent it

  • Pin store-dir to a stable path.
  • Cache the pnpm store, not node_modules.
  • Keep HOME/user consistent across CI runs.

Frequently asked questions

What causes pnpm "ERR_PNPM_UNEXPECTED_STORE"?
There are 2 common causes: node_modules restored from a different store path and the store path changed between runs. A cached node_modules built where the pnpm store sat at one path is restored on a runner whose store path differs (different HOME/user), so the recorded store no longer matches.
How do I fix pnpm "ERR_PNPM_UNEXPECTED_STORE"?
There are 2 fixes depending on which cause you have: reset node_modules and pin the store path and cache the store, not node_modules. Work through them in order, since the first is the most common.
What does pnpm "ERR_PNPM_UNEXPECTED_STORE" actually mean?
pnpm install aborts with ERR_PNPM_UNEXPECTED_STORE, reporting that node_modules was created with a different store location.
How do I stop pnpm "ERR_PNPM_UNEXPECTED_STORE" happening again?
Pin store-dir to a stable path. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card