EAS_GRADLE_CACHE: cleanup never removes entries, so saves permanently fail once the archive exceeds ~2 GiB
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 236
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 91
Description
### Build/Submit details page URL
https://expo.dev/accounts/asula/projects/dawn-xyz/builds/10d1908e-424c-45ce-a460-ab7d8b97435d
### Summary
With `EAS_GRADLE_CACHE=1`, the build cache enters a permanent failure loop on active projects:
1. The cleanup configured by your init script does nothing — its own log proves it: `[EAS] Gradle build cache entries before cleanup: 5199` → `after build: 5337 (was 5199)`, growth on every build, never a removal (retention likely can't fire because extraction resets entry timestamps).
2. Once the archive crosses ~2 GiB, the storage PUT in `uploadCacheAsync` is rejected — `Error: Unexpected response from cache server (400): Bad Request` — on every build:
```
Gradle cache archive size: 2.2 GB
Uploading cache...
Failed to save Gradle cache
```
3. The exact key is therefore never written, so every restore is a prefix match of the same stale oversized archive — the loop never self-heals, even across lockfile changes.
4. All of this is silent: builds succeed and the 400 is only visible in the structured log's `err` field.
Likely related: the ccache prune before save (`ccache --evict-older-than s`) evicts objects written *during* the build — a 30-min build with ~17k ccache writes saved a 10.8 MB archive, and the next build restored a cache with 16 files / 0.0 GiB. So neither cache layer persists, and all C++ recompiles every build.
Suggested: validate size at session creation (or raise the cap), log the PUT response body, surface save failures in the UI, and make retention work on ephemeral workers.
### Managed or bare?
Managed (CNG/prebuild)
### Environment
Server-side EAS Build issue — image `ubuntu-26.04-jdk-17-ndk-r27b`, resource class `medium`, SDK 56 / RN 0.85, pnpm, ~13 CMake native modules. Local env not relevant.
### Error output
_No response_
### Reproducible demo or steps to reproduce from a blank project
Time/scale-dependent, not reproducible from a blank project — but observable on any project: enable `EAS_GRADLE_CACHE=1`, run two builds, and watch the init-script entry counts only increase regardless of the 3-day retention. Once accumulated past ~2 GiB (weeks, for a project with many native modules and several profiles sharing the lockfile-hash key), every save 400s. Example builds from 2026-07-02: `10d1908e-424c-45ce-a460-ab7d8b97435d` (production), `0a01138e-6bea-4141-8dc9-3dc74e6c8880` (staging). Full logs available on request.
Main cuts: the impact section, the restore/error log blocks (kept one-line quotes inline), four of the six suggested fixes, the env-info dump (replaced with the one line that matters — it's a server-side bug), and the ccache detail compressed to one paragraph. If they push back on the missing expo-env-info output, it takes 10 seconds to paste in from my previous message.
Contributor guide
Assessment
This issue has not been assessed yet.