Files
sbt/notes/2.0.0/cache-environmental-compile-failure.md
T
BrianHotoppandClaude Opus 4.8 b411ade704 [2.x] fix: Don't cache environmental (position-less) compile failures (#9464)
Failure caching assumes a CompileFailed is a function of
the sources, which is true for source errors. But zinc also surfaces I/O write
failures ("error writing X.class") as compiler problems, so an environmental
failure (a concurrent target/ deletion, a permission blip) was cached under the
same mechanism and replayed from the global action cache on every later build,
even after the cause was gone. When the poisoned task is the metabuild compile
this is self-sustaining and unrecoverable from inside sbt: project loading
fails, so no task -- including clean -- can run, and only deleting the global
cache by hand recovers. The replayed diagnostics also name files/permissions
that no longer exist.

Refs #9455

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-18 09:49:05 -04:00

1.0 KiB

Environmental compile failures are no longer cached

sbt caches a CompileFailed so that an unchanged, still-broken compile does not re-run from scratch (#7662). But zinc also reports I/O write failures ("error writing X.class") as compiler problems, so a one-off environmental failure (a concurrent target/ deletion, a permission blip) was cached under the same mechanism and replayed on every later build, even after the cause was gone. When it hit the metabuild compile the build stayed wedged across restarts, recoverable only by deleting the global cache by hand. Compile failures whose errors carry no source position are now treated as environmental and left uncached, so the next build retries for real. A position-less failure already sitting in a cache written by an earlier sbt is likewise no longer replayed: the task re-runs and a success overwrites the stale entry, so previously wedged builds recover on upgrade without deleting the cache.

This addresses #9455.