skip to content

What do allWarningsAsErrors and freeCompilerArgs do in the Kotlin compilerOptions block, and what are the tradeoffs of enabling allWarningsAsErrors in CI?

level: middleimportance: should knowfreq 40%

answer

  1. allWarningsAsErrors = warnings become build-failing errors
  2. Risk: compiler upgrade adds new warnings -> red build
  3. freeCompilerArgs = passthrough for -X experimental flags
  4. Use freeCompilerArgs.add(), not .set()
  5. -X flags are unstable across versions

basics

~10 s

allWarningsAsErrors makes every compiler warning fail the build, keeping code clean. freeCompilerArgs is an escape hatch list for passing extra/experimental -X compiler flags that don't have a typed DSL property yet.

solid answer

~40 s

compilerOptions.allWarningsAsErrors is a boolean that promotes all Kotlin compiler warnings (deprecations, unchecked casts, unused, etc.) to errors so the build fails — great for enforcing zero-warning hygiene in CI. The tradeoff: a new compiler version can introduce fresh warnings that suddenly break a previously-green build, and third-party-deprecation warnings you can't fix can block you, so teams often pair it with targeted suppressions or gate it per-module. compilerOptions.freeCompilerArgs is a ListProperty<String> escape hatch for arbitrary flags — typically experimental -X options (e.g. "-Xcontext-parameters", "-Xjsr305=strict", opt-in flags) that lack a first-class typed DSL property. Use freeCompilerArgs.add(...) rather than .set(...) so you don't clobber args the plugin already added.

go deeper

for a junior

Knows allWarningsAsErrors makes warnings fail the build and freeCompilerArgs passes extra flags.

for a middle

Explains the CI upgrade/third-party-deprecation tradeoffs and the add-vs-set rule for freeCompilerArgs.

for a senior

Designs a per-module warning policy, balances hygiene against upgrade churn, and knows -X flags are unstable.

for a principal

Sets org standards for warning enforcement and opt-in flags, planning compiler-upgrade rollouts so allWarningsAsErrors doesn't block teams.

## allWarningsAsErrors A boolean compiler option. When `true`, **every** Kotlin compiler warning is escalated to a compile **error**, failing the build. Warnings include things like deprecation usage, unchecked casts, redundant code, and unused declarations. ```kotlin kotlin { compilerOptions { allWarningsAsErrors.set(true) } } ``` **Why teams enable it:** it enforces a *zero-warning* policy, so warnings don't silently accumulate and get ignored. This catches deprecated-API usage early. **Tradeoffs / risks:** - **Compiler upgrades break the build.** A newer Kotlin compiler may emit warnings the old one didn't (new deprecations, new inspections), turning a green build red on upgrade. - **Unfixable third-party warnings.** A deprecated API in a dependency you can't change still produces a warning → now an error. You must `@Suppress` it locally or carve out an exception. - Often applied **per module** or combined with explicit `@Suppress("...")` for known, accepted warnings. ## freeCompilerArgs A `ListProperty<String>` that passes **raw compiler arguments** straight through to `kotlinc`. It's the **escape hatch** for flags that don't yet have a typed property in the Gradle DSL — almost always experimental `-X` flags or opt-in switches: ```kotlin kotlin { compilerOptions { // ADD, don't SET, so you keep flags the plugin already configured freeCompilerArgs.add("-Xjsr305=strict") freeCompilerArgs.add("-Xcontext-parameters") freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") } } ``` **Key practice:** use `.add(...)` / `.addAll(...)` rather than `.set(listOf(...))`. The Kotlin Gradle plugin may inject its own args (e.g. for plugins or modules); calling `.set` overwrites them and can break the build in subtle ways. **Caveat:** `-X` flags are unstable/experimental by definition — they can change or vanish between Kotlin versions, so don't rely on them for long-lived production builds without owning the upgrade risk. ## Relationship `allWarningsAsErrors` is a typed, supported knob for build hygiene; `freeCompilerArgs` is the untyped passthrough for everything the DSL hasn't surfaced yet. They're independent and frequently both appear in the same `compilerOptions` block.

  • Why prefer freeCompilerArgs.add over .set?
    The Kotlin Gradle plugin may have already added arguments; .set replaces the whole list and silently drops them, while .add appends safely.
  • What's a downside of allWarningsAsErrors when bumping Kotlin?
    The new compiler may emit warnings the old one didn't, turning a passing build into a failing one until you fix or suppress them.

saying these in an interview costs you the question

  • Thinking freeCompilerArgs is for runtime/JVM args
  • Using freeCompilerArgs.set and clobbering plugin-added flags
  • Claiming allWarningsAsErrors has no downside on compiler upgrades
  • Not knowing -X flags are experimental/unstable
  • Confusing allWarningsAsErrors with suppressing warnings

context