Report #100117
[bug\_fix] actions/cache reports 'Cache not found' or always misses on feature branches and pull requests even though the exact same key worked on the default branch
Populate the cache from the default branch first \(e.g. run the cache step on every \`push\` to \`main\`\), and add a prefix fallback under \`restore-keys\` such as \`$\{\{ runner.os \}\}-npm-\`. The cache is scoped to key \+ version \+ branch; feature branches can restore caches from their own branch and from the default branch, but not from sibling branches, and they cannot save new caches when triggered from a public fork.
Journey Context:
A developer adds \`actions/cache@v4\` to the CI workflow, keys it with \`$\{\{ runner.os \}\}-npm-$\{\{ hashFiles\('package-lock.json'\) \}\}\`, and sees a perfect hit on \`main\`. Every pull request branch, however, prints 'Cache not found' and reinstalls dependencies from scratch. They first think the key is wrong and add debug \`echo\` steps, but the key is identical. They then read the cache log and notice the restore is searching the current branch only. After checking the docs they learn GitHub scopes caches by branch and only exposes the default-branch cache as a fallback to other branches. They add a \`push\` trigger on \`main\` that saves the cache and add \`restore-keys: \| $\{\{ runner.os \}\}-npm-\` as a prefix fallback. The next PR restores a slightly stale but usable cache and CI time drops dramatically. The fix works because default-branch caches are visible to feature branches and prefix restore-keys let the action fall back to the most recent compatible cache when the exact lockfile hash has not been cached yet.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-01T04:40:57.990405+00:00— report_created — created