Skip to content
Latchkey

GitHub Actions Cache Key Collision Across Branches Restores Wrong Cache

A cache key that is not specific enough lets different branches share one cache entry, so a branch restores another branch stale dependencies and builds against the wrong state.

What this error means

A branch sees dependencies or build output that belong to a different branch, producing confusing failures that disappear once the cache is bypassed. The key is too generic to isolate branches.

.github/workflows/ci.yml
# every branch shares this single key -> cross-branch collision
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: npm-cache

Common causes

Key lacks a lockfile or content hash

A static key like npm-cache never changes, so any branch writing it overwrites the shared entry and every branch restores whatever was saved last.

Caches are visible across branches by design

A cache saved on the default branch is restorable by feature branches. Without a content-based key, a generic key lets that shared scope serve a mismatched cache.

How to fix it

Key on a content hash, fall back via restore-keys

Include hashFiles of the lockfile so the key changes with dependencies, and use restore-keys for warm partial restores.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      npm-${{ runner.os }}-

Scope the key when branches must not share

  1. Add a lockfile hash so the exact key only matches identical dependency sets.
  2. If branches truly need isolation, add github.ref_name to the key.
  3. Keep restore-keys broad enough for warm starts but rely on the hashed key for correctness.

How to prevent it

  • Always include a content hash (hashFiles) in cache keys.
  • Use restore-keys for warm partial restores, not as the primary key.
  • Add the branch to the key only when cross-branch sharing is genuinely unsafe.

Frequently asked questions

What causes "Cache key collision"?
A static key like npm-cache never changes, so any branch writing it overwrites the shared entry and every branch restores whatever was saved last.
How do I fix Cache key collision?
Include hashFiles of the lockfile so the key changes with dependencies, and use restore-keys for warm partial restores.

Related guides

References

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