Summary
When a workflow uses cache-memory together with threat detection, the generated update_cache_memory job (and the conclusion job's daily-AIC usage cache save) fails to write the GitHub Actions cache with:
Cache reservation failed: cache write denied: token has no writable scopes
The cache save steps are continue-on-error: true, so the run stays green — but the cache is never persisted, silently defeating cross-run cache-memory.
Root cause
pkg/workflow/cache.go → buildUpdateCacheMemoryJob assigns the job empty permissions:
permissions := NewPermissionsEmpty().RenderToYAML() // Default: no special permissions needed
if setupActionRef != "" && len(c.generateCheckoutActionsFolder(data)) > 0 {
permissions = NewPermissionsContentsRead().RenderToYAML() // dev mode only
}
The comment "no special permissions needed" is incorrect: GitHub's cache-reservation backend requires a writable token scope. The generated job therefore gets permissions: {} (or at most contents: read), and the reservation is denied.
Key detail: the cache backend accepts only actions/contents write as a "writable scope". It does not accept issues/pull-requests write — our conclusion job carries issues: write + pull-requests: write (from safe-outputs) and its daily-AIC cache save still fails with the same "no writable scopes" error. So the fix must be actions: write specifically.
This is on main, not just a released version.
Impact
update_cache_memory: cross-run cache-memory never persists → the feature is effectively a no-op on affected repos.
conclusion: the daily-AIC usage cache save fails (artifact fallback per ADR-39266 partially mitigates, but the cache lineage never forms).
- Repos with a read-only default
GITHUB_TOKEN (Settings → Actions → Workflow permissions = read) are always affected; and because the job sets permissions: {} explicitly, even a read-write default token is overridden to zero — so it fails regardless of the org/repo default.
No configuration workaround
Per reference/permissions.md, the frontmatter permissions: block governs the agent job's read scopes (writes go through safe-outputs); it does not reach these compiler-generated infra jobs. So there is no frontmatter/recompile/upgrade way to grant the scope — the job's permissions are hardcoded in the compiler.
Proposed fix
Emit actions: write on the cache-save jobs:
update_cache_memory (buildUpdateCacheMemoryJob, pkg/workflow/cache.go)
- the daily-AIC usage cache save in the
conclusion job (pkg/workflow/notify_comment.go)
(actions: write is the scope GitHub documents for cache mutation; contents: write also works but is broader than needed.)
Environment
- gh-aw:
v0.81.6 (latest release at time of writing); root cause also present on main.
- Affected regardless of
actions/cache major version (reproduced on both v5.0.5 and v6.1.0).
- Workflow config:
tools.cache-memory: true, safe-outputs (threat detection enabled), permissions: read-all, repo default workflow token = read-only.
Searched existing issues/PRs for "cache", "writable scopes", "actions: write", "cache save permission" — found none tracking this.
Summary
When a workflow uses
cache-memorytogether with threat detection, the generatedupdate_cache_memoryjob (and theconclusionjob's daily-AIC usage cache save) fails to write the GitHub Actions cache with:The cache save steps are
continue-on-error: true, so the run stays green — but the cache is never persisted, silently defeating cross-runcache-memory.Root cause
pkg/workflow/cache.go→buildUpdateCacheMemoryJobassigns the job empty permissions:The comment "no special permissions needed" is incorrect: GitHub's cache-reservation backend requires a writable token scope. The generated job therefore gets
permissions: {}(or at mostcontents: read), and the reservation is denied.Key detail: the cache backend accepts only
actions/contentswrite as a "writable scope". It does not acceptissues/pull-requestswrite — ourconclusionjob carriesissues: write+pull-requests: write(from safe-outputs) and its daily-AIC cache save still fails with the same "no writable scopes" error. So the fix must beactions: writespecifically.This is on
main, not just a released version.Impact
update_cache_memory: cross-runcache-memorynever persists → the feature is effectively a no-op on affected repos.conclusion: the daily-AIC usage cache save fails (artifact fallback per ADR-39266 partially mitigates, but the cache lineage never forms).GITHUB_TOKEN(Settings → Actions → Workflow permissions = read) are always affected; and because the job setspermissions: {}explicitly, even a read-write default token is overridden to zero — so it fails regardless of the org/repo default.No configuration workaround
Per
reference/permissions.md, the frontmatterpermissions:block governs the agent job's read scopes (writes go through safe-outputs); it does not reach these compiler-generated infra jobs. So there is no frontmatter/recompile/upgrade way to grant the scope — the job's permissions are hardcoded in the compiler.Proposed fix
Emit
actions: writeon the cache-save jobs:update_cache_memory(buildUpdateCacheMemoryJob,pkg/workflow/cache.go)conclusionjob (pkg/workflow/notify_comment.go)(
actions: writeis the scope GitHub documents for cache mutation;contents: writealso works but is broader than needed.)Environment
v0.81.6(latest release at time of writing); root cause also present onmain.actions/cachemajor version (reproduced on bothv5.0.5andv6.1.0).tools.cache-memory: true,safe-outputs(threat detection enabled),permissions: read-all, repo default workflow token = read-only.Searched existing issues/PRs for "cache", "writable scopes", "actions: write", "cache save permission" — found none tracking this.