Skip to content
Latchkey

GitHub Actions cache/restore Never Saves - Missing cache/save Step

A cache never gets populated because the workflow uses actions/cache/restore on its own. The split restore/save actions do not auto-save at job end - only the combined actions/cache does - so you must add a cache/save step.

What this error means

Every run is a cache miss because nothing ever saves the cache. The restore step runs but no corresponding save persists the directory after the build.

.github/workflows/ci.yml
# restore only - cache is never written back
- uses: actions/cache/restore@v4
  with: { path: ~/.npm, key: npm-${{ hashFiles('package-lock.json') }} }
- run: npm ci
# (no actions/cache/save step) -> next run misses again

Common causes

Split restore without save

actions/cache/restore only reads. Unlike the combined actions/cache, it has no post step that saves, so without an explicit save the cache is never written.

Assuming auto-save like the combined action

The combined actions/cache saves automatically at job end. The restore/save split trades that convenience for control, so you own the save step.

How to fix it

Add a matching cache/save step

Save with the same key (often gated on a cache miss) after the build produces the directory.

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

Or use the combined action

  1. Switch to actions/cache when you want automatic restore + save.
  2. Use restore/save split only when you need to control when the save happens.
  3. Keep the save key consistent with the restore key.

How to prevent it

  • Pair every actions/cache/restore with an actions/cache/save.
  • Use the combined actions/cache when you do not need split control.
  • Gate the save on a cache miss to avoid redundant uploads.

Related guides

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