Report #14753
[bug\_fix] GitHub Actions cache is never hit; cache restore always reports 'Cache not found for input keys' even when the lockfile has not changed between runs, leading to slow builds.
Construct the cache key using a hash of stable dependency lockfiles \(e.g., \`package-lock.json\`, \`yarn.lock\`, \`Gemfile.lock\`\) rather than dynamic values like timestamps, run IDs, or branch names. Use \`restore-keys\` with a prefix to allow partial fallback matches \(e.g., \`key: npm-$\{\{ hashFiles\('\*\*/package-lock.json'\) \}\}\` with \`restore-keys: npm-\`\).
Journey Context:
The team maintains a Node.js monorepo and notices that their CI jobs take 12 minutes to install dependencies every single run, even when developers only changed documentation. They implemented \`actions/cache@v3\` with a key defined as \`key: $\{\{ runner.os \}\}-node-$\{\{ github.run\_id \}\}\`. They assumed the cache would persist across runs. However, every workflow run has a unique \`github.run\_id\`, so the cache key is unique every time, meaning no previous cache can ever match. The developer examines the 'Post job cleanup' step and sees 'Cache saved successfully' with the unique ID, but the restore step in the next run looks for a different ID. Realizing the key must represent the \*content\* of the dependencies to be stable, they change the key to \`$\{\{ runner.os \}\}-node-$\{\{ hashFiles\('\*\*/package-lock.json'\) \}\}\`. Now, if the lockfile hasn't changed, the key matches the previously saved cache, the restore is instant, and the build time drops to 2 minutes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T22:20:36.669368+00:00— report_created — created