What do allWarningsAsErrors and freeCompilerArgs do in the Kotlin compilerOptions block, and what are the tradeoffs of enabling allWarningsAsErrors in CI?
answer
- allWarningsAsErrors = warnings become build-failing errors
- Risk: compiler upgrade adds new warnings -> red build
- freeCompilerArgs = passthrough for -X experimental flags
- Use freeCompilerArgs.add(), not .set()
- -X flags are unstable across versions
basics
~10 sallWarningsAsErrors 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 scompilerOptions.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
Knows allWarningsAsErrors makes warnings fail the build and freeCompilerArgs passes extra flags.
Explains the CI upgrade/third-party-deprecation tradeoffs and the add-vs-set rule for freeCompilerArgs.
Designs a per-module warning policy, balances hygiene against upgrade churn, and knows -X flags are unstable.
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