Skip to content
Latchkey

CircleCI Partial Cache Restore Brings Stale Deps - Fix Fallbacks

After a lockfile change, the exact cache key misses, a broad prefix fallback restores an old cache, and the install step does not reconcile it - so the job runs with stale dependencies that pass cache lookup but no longer match the lockfile.

What this error means

The build "restores cache" but then fails or behaves oddly because the installed dependency set predates the latest lockfile change. The exact-key miss fell through to a prefix fallback, and nothing re-resolved against the new lockfile.

job log
restore_cache
  - Searching: deps-v1-{{ checksum "package-lock.json" }}  (no hit)
  - Found via fallback: deps-v1-  (older cache)
# install skipped because node_modules "looked" present -> stale deps

Common causes

Prefix fallback restores an old cache

A broad fallback key like deps-v1- is meant to warm the package cache, but if the job treats a restored node_modules as "already installed", it never updates to the new lockfile.

Install step is conditional on a missing directory

Skipping npm ci when node_modules exists means a fallback-restored, stale node_modules is used as-is instead of reconciled.

Caching node_modules instead of the package cache

Caching node_modules directly makes a partial restore look complete; caching ~/.npm and always running npm ci avoids stale trees.

How to fix it

Always install against the lockfile, cache the package cache

.circleci/config.yml
- restore_cache:
    keys:
      - deps-v1-{{ checksum "package-lock.json" }}
      - deps-v1-
- run: npm ci          # always reconcile to the lockfile
- save_cache:
    key: deps-v1-{{ checksum "package-lock.json" }}
    paths: [~/.npm]

Never skip install on a cache hit

  1. Run the deterministic install (npm ci, poetry install) every job, regardless of restore.
  2. Treat restored caches as a speedup, not a substitute for installing.
  3. Cache the package manager cache dir, not the resolved module tree.

How to prevent it

  • Always run a lockfile-deterministic install, even after a cache hit.
  • Cache the package manager cache, not node_modules.
  • Use prefix fallbacks only to warm the cache, never to skip installing.

Frequently asked questions

What causes "stale partial restore"?
A broad fallback key like deps-v1- is meant to warm the package cache, but if the job treats a restored node_modules as "already installed", it never updates to the new lockfile.
How do I fix stale partial restore?
Always install against the lockfile, cache the package cache

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card