Skip to content
Latchkey

sbt "-Xfatal-warnings" turning warnings into errors in CI

The build sets -Xfatal-warnings (or -Werror on Scala 3), so every compiler warning is promoted to an error. Code that compiles with warnings locally fails the CI compile with the underlying warning shown as an error.

What this error means

scalac fails and the last line reads that the build cannot proceed because warnings are fatal, with the real warning (unused import, deprecation, exhaustiveness) printed just above.

scalac
[error] /src/main/scala/App.scala:3:8: Unused import
[error] import scala.collection.mutable
[error]        ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Common causes

A real warning is now fatal

An unused import, a deprecation, or a non-exhaustive match produced a warning that -Xfatal-warnings converts into a build-failing error.

A new compiler or dependency version added a warning

Upgrading Scala or a library introduced a deprecation warning that did not exist before, and fatal warnings turn it into a failure.

How to fix it

Fix the underlying warning

  1. Read the warning printed above the failure (unused import, deprecated call, missing case).
  2. Correct it in the source rather than suppressing it globally.
  3. Recompile to confirm no warnings remain.
App.scala
// remove the unused import, or address the deprecation it flags

Scope or relax fatal warnings deliberately

If a warning is intentional, silence just that category with @nowarn or narrow -Wconf rather than dropping fatal warnings entirely.

App.scala
import scala.annotation.nowarn
@nowarn("cat=deprecation")
def legacyCall(): Unit = oldApi()

How to prevent it

  • Keep -Xfatal-warnings on locally so warnings fail before CI.
  • Address deprecations promptly instead of accumulating them.
  • Use -Wconf or @nowarn for narrowly justified exceptions.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →