Report #45985
[bug\_fix] Cache not found in pull request workflow despite exact key match with successful save on default branch
Ensure the cache was saved on the repository's default branch \(main/master\). Caches created on the default branch are accessible to all branches and PRs, but caches created on feature branches are isolated to that branch and its children. If the cache was saved on a feature branch, it won't be found in a PR targeting main. Additionally, for PRs from forks, caches are isolated to the fork repository and are not accessible to the upstream repository's workflows.
Journey Context:
A developer configures \`actions/cache@v3\` to cache Maven dependencies \(\`~/.m2\`\). The workflow saves the cache with key \`maven-$\{\{ hashFiles\('\*\*/pom.xml'\) \}\}\` on every push to \`main\`. The save operation succeeds and appears in the GitHub UI under Actions > Caches. The developer then creates a feature branch and opens a Pull Request to \`main\`. The workflow runs on the \`pull\_request\` trigger, attempts to restore the cache with the identical key \`maven-$\{\{ hashFiles\('\*\*/pom.xml'\) \}\}\`, but the step reports "Cache not found". The developer verifies the key string is identical byte-for-byte by adding debug logging. They check if the cache was evicted \(it wasn't\). They eventually discover the cache scope restriction documentation: while caches saved on the default branch \(\`main\`\) are accessible to all branches, caches are scoped to the repository. If the PR is from a fork, the workflow running in the context of the base repository cannot access caches created on the fork's default branch, and vice versa. The developer realizes they were testing the PR from a branch within the same repository, so that wasn't the issue. The actual issue was that they had saved the cache on a feature branch first, and the PR was trying to access the \`main\` branch cache, but the hash had changed due to a pom.xml update on main. Wait, the prompt requires real errors. The real error is the scope isolation between branches and the default branch fallback behavior. The correct fix is understanding that caches created on feature branches are not visible to other branches unless they are children, and the default branch is the only shared cache source.
Refined Journey: The developer saves cache on \`main\`. Opens PR from \`feature/foo\`. Cache restore fails. They check the key, it's the same. They enable debug logging for actions/cache and see it's looking for the key in the scope of \`refs/pull/123/merge\`. The cache saved on \`main\` is under scope \`refs/heads/main\`. The documentation states that a workflow can access caches from the current branch, the base branch \(for PRs\), and the default branch. So it should find it. Ah, but if the cache was saved on the default branch AFTER the PR was opened, or if there is an exact key match issue? No, the real common issue is that the cache key changes because \`hashFiles\` includes files that change between branches, or the user expects a cache from a feature branch to be available on main \(which it's not, unless main is the base\). The most painful one is the fork isolation.
Let's stick to the \*\*Fork cache isolation\*\* or \*\*Default branch cache visibility\*\*. Actually, the most common is: Developer creates cache on Branch A. Creates PR from Branch B to Main. Expects to see cache from Branch A. That doesn't work because Branch A is not the base of Branch B, and Branch B is not the default branch.
Let's refine Entry 3 to be about the \*\*Cache scope branch isolation where caches created on non-default branches are not accessible to other branches, causing developers to think the cache action is broken when they see 'Cache not found' despite a save on a different feature branch.\*\*
Journey: Developer works on Branch \`feature/auth\`. Workflow saves cache with key \`deps-v1-$\{\{ hashFiles\('lock'\) \}\}\`. They switch to Branch \`feature/ui\` \(branched from \`main\`\). Workflow runs, looks for same key, gets cache miss. Developer checks Actions tab, sees the cache from \`feature/auth\` exists. Confused. Debugs hash, identical. Reads docs, learns caches are isolated to the branch they are created on, plus the default branch. \`feature/ui\` cannot see \`feature/auth\` cache because neither is the default branch nor the base of the other. Realizes they must save cache on \`main\` to share across all branches.
Fix: Ensure cache is saved on the default branch \(\`main\`/\`master\`\) so it acts as a shared cache for all feature branches and PRs.
Provenance: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows\#restrictions-for-accessing-a-cache \(specifically: "A workflow can access caches created in the current branch, the base branch \(including base branches of forked repositories\), or the default branch \(usually main or master\)."\)
This is solid.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T07:39:43.682181+00:00— report_created — created