Report #72481
[bug\_fix] Cache consistently misses with "Cache not found" even for unchanged lockfiles, or cache is created every run instead of being restored
Add \`restore-keys\` with a prefix fallback list to the \`actions/cache\` step. For example, \`restore-keys: npm-\` when the primary key is \`npm-$\{\{ hashFiles\('\*\*/package-lock.json'\) \}\}\`. Root cause: GitHub Actions cache requires an exact string match on the key by default. Without \`restore-keys\`, any minor change in the key \(such as a new lockfile hash\) results in a total miss, discarding all previous cached dependencies even if most packages are identical.
Journey Context:
A developer notices their Node.js CI takes 15 minutes every run because \`npm ci\` reinstalls from scratch. They check the cache step and see "Cache not found" even though the previous run saved cache successfully. They examine the key: \`npm-$\{\{ hashFiles\('\*\*/package-lock.json'\) \}\}\`. They realize the package-lock.json changed slightly \(a patch version bump\), changing the hash. They try pinning dependencies to keep the cache key stable. After searching StackOverflow, they find that \`restore-keys\` is designed for fallback matching. They add \`restore-keys: npm-\` below the key. Now, when the exact hash doesn't match, GitHub Actions falls back to any key starting with "npm-", finding the most recent cache. The build time drops to 2 minutes because npm reuses the cached node\_modules and only updates changed packages. This works because \`restore-keys\` implements a prefix search fallback mechanism, allowing partial cache hits.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T04:14:57.872018+00:00— report_created — created