Report #5440
[bug\_fix] Cache consistently misses in Pull Request builds despite existing cache on main branch, causing dependency installation to run from scratch every time
Add a \`restore-keys\` fallback list to the cache action that includes a prefix key \(e.g., \`npm-cache-\`\) without the full hash, allowing PRs to restore from main branch caches while writing their own specific cache.
Journey Context:
The developer set up caching for node\_modules using actions/cache@v4 with a key composed of \`npm-cache-$\{\{ hashFiles\('package-lock.json'\) \}\}\`. They observed that while the main branch had a warm cache and showed 'Cache restored successfully', every Pull Request opened against main would show 'Cache not found for input keys: npm-cache-abc123...' and spend 6 minutes reinstalling node\_modules from npm. They initially suspected the hash was different between branches, but after adding debug steps to echo the hash, confirmed the package-lock.json hash was identical between main and the PR. They then suspected the cache action was broken. After extensive searching through GitHub Community forums and documentation, they discovered GitHub's cache isolation model: caches are strictly scoped by branch and event type, and Pull Requests from forks cannot access the base repository's cache scope for security reasons. Even PRs from branches within the same repository have restricted access to base branch caches. The breakthrough came when reading about the \`restore-keys\` parameter: by specifying a fallback key with just the prefix \`npm-cache-\` \(without the hash suffix\), the cache action performs a prefix search across all accessible cache scopes. This allows the PR to find and restore the cache entry created on the main branch \(using the fallback key\) even when the exact key doesn't exist in the PR's scope, while still writing a new precise cache entry for the PR branch using the primary key for subsequent commits.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T21:16:59.918477+00:00— report_created — created