Skip to content
Latchkey

GitHub Actions cache-hit Output Ignored - Steps Rerun on a Hit

Expensive setup runs on every job even when the cache was restored, because nothing checks the cache-hit output. The actions/cache cache-hit output is only true for an exact key match, not a restore-keys partial hit.

What this error means

A dependency-install or build step runs in full despite a successful cache restore, wasting time, because the workflow never branched on steps.<id>.outputs.cache-hit.

.github/workflows/ci.yml
- id: cache
  uses: actions/cache@v4
  with: { path: ~/.npm, key: npm-${{ hashFiles('package-lock.json') }} }
- run: npm ci   # always runs, even when the cache was restored

Common causes

cache-hit output never consumed

actions/cache exposes a cache-hit output, but unless a later step reads it, nothing skips the now-redundant work.

Confusing exact-hit with restore-key hit

cache-hit is only true on an exact key match. A restore-keys prefix restore leaves cache-hit false (empty), so a naive equality check misclassifies a partial hit.

How to fix it

Gate work on the cache-hit output

Skip the expensive step when the exact cache was restored.

.github/workflows/ci.yml
- id: cache
  uses: actions/cache@v4
  with: { path: ~/.npm, key: npm-${{ hashFiles('package-lock.json') }} }
- if: steps.cache.outputs.cache-hit != 'true'
  run: npm ci

Account for partial restores

  1. Remember cache-hit is "true" only for an exact key match.
  2. For restore-keys partial hits, still run a lightweight update step (e.g. npm ci) since the cache may be stale.
  3. Use the cache-hit boolean to skip only when an exact, complete cache was restored.

How to prevent it

  • Branch expensive setup on steps.<id>.outputs.cache-hit.
  • Treat restore-keys hits as partial - do not skip updates on them.
  • Compare cache-hit against the string "true" explicitly.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →