skip to content

Why does detekt's autoCorrect option leave most findings unfixed in a Gradle build?

level: middleimportance: nice to knowfreq 30%

answer

  1. It is a permission, not a capability
  2. A rule must implement its own correction
  3. Design findings need a human decision
  4. Formatting rules arrive from an optional artifact
  5. A correcting run mutates the checked-out sources

basics

~20 s

Because autoCorrect only reaches rules that implement a correction. Most detekt rules describe a design problem with no mechanical fix — a long method or a magic number cannot be rewritten automatically — so they stay reported no matter how the flag is set.

solid answer

~50 s

`autoCorrect` in the `detekt {}` Gradle extension (or `--auto-correct` on the CLI) turns on correction for rules that **can** correct; it does not make every rule fixable. detekt's analysis rules — `LongMethod`, `MagicNumber`, `CyclomaticComplexMethod`, `SwallowedException` — report a judgment about design, and there is no safe mechanical rewrite for any of them. The correctable rules are overwhelmingly the formatting ones contributed by the optional `detekt-formatting` artifact, which you add to the `detektPlugins` configuration; it wraps ktlint's rules and those genuinely can rewrite whitespace, indentation and import order. Two operational points follow: correction mutates source files, so it belongs in a local or pre-commit task, never in the verification run CI gates on; and a correcting run still reports what it fixed, so a red build after autoCorrect usually means the remaining findings were never automatable.

code

kotlin · 12 lines
kotlin
plugins {
    id("io.gitlab.arturbosch.detekt") version "1.23.8"
}

dependencies {
    detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.8")
}

detekt {
    // Local convenience only — the task CI verifies with must stay read-only.
    autoCorrect = true
}

go deeper

for a junior

Recall that autoCorrect only fixes mechanical, formatting-shaped findings, and that design findings such as a long method always need a human change.

for a middle

Explain the mechanism: the flag grants permission, each rule decides whether it can correct, and the correctable population comes mostly from the optional formatting rule set loaded via detektPlugins.

for a senior

Show the operational judgment — a correcting run mutates the workspace, so verification tasks stay read-only and correction lives where a developer reviews the resulting diff.

for a principal

Own where mechanical fixing sits in the toolchain overall: which tool is permitted to rewrite sources, at which point in the developer loop, and how that stays consistent across repositories.

## What autoCorrect actually is detekt's Gradle extension exposes `autoCorrect` as a boolean (`--auto-correct` on the command line). It is a *permission*, not a capability: it tells the run that rules which know how to rewrite code are allowed to do so. Each rule carries an auto-correct flag internally; a rule that has no correction logic simply ignores the permission and reports as usual. That is why teams are surprised. Setting the flag and re-running produces a build that is still red, with `MagicNumber`, `LongMethod` and friends untouched, and the natural conclusion — "autoCorrect is broken" — is wrong. ## Why most detekt rules cannot correct Think about what a correction would mean for each rule. `LongMethod` fires because a function is doing too much; the fix is a decomposition that requires knowing which parts belong together. `MagicNumber` fires because a literal has no name; the fix requires choosing that name. `SwallowedException` fires because an error was discarded; the fix requires deciding what should happen instead. `CyclomaticComplexMethod` fires because control flow is dense; the fix is a redesign. Every one of those is a judgment. A tool that guessed would produce a diff nobody could review and would sometimes be wrong in ways that compile. detekt deliberately does not guess: rules whose findings need a human decision only report. ## Which rules can correct The correctable population is dominated by formatting rules, which arrive through the optional `detekt-formatting` artifact added to the `detektPlugins` Gradle configuration. Those rules wrap ktlint's implementations, and whitespace, indentation, trailing commas and import ordering are exactly the class of problem where the correct output is uniquely determined — there is nothing to decide, so rewriting is safe. A small number of built-in rules also support correction, but the practical answer in an interview is: formatting corrects, analysis reports. ## Wiring it up The plugin and the extra rules must be on the same version, and the extra rule set has to be declared as a `detektPlugins` dependency rather than a normal `implementation` one, since it is loaded into the detekt run, not into your application. Version note: detekt 1.x publishes the Gradle plugin as `io.gitlab.arturbosch.detekt`, while detekt 2.0 moves it to `dev.detekt` — the extension property itself is spelled `autoCorrect` in both. ## The CI hazard A correcting run **writes to your source tree**. That has two consequences worth stating unprompted. First, never enable it on the task CI uses to verify the build. If the checked-out sources are modified during verification, the pipeline is no longer testing the commit under review, and the fixes evaporate when the agent's workspace is discarded — the same violation returns on the next run. Verification tasks must be read-only. Second, put correction where a human sees the diff: a local Gradle invocation, a pre-commit hook, or an explicit "format" task developers run on purpose. The reviewable artefact is then a committed change, not an invisible mutation. ## What to expect after a correcting run The run still reports. Findings it fixed are addressed on disk; findings it could not fix remain, and the task fails on them exactly as before. So the healthy interpretation of "I enabled autoCorrect and the build is still red" is simply that the remaining findings were never in the automatable class — which is the majority of what detekt exists to tell you.

  • Why must a CI verification task never run detekt with autoCorrect enabled?
    Because correction writes to the checked-out sources. The pipeline then verifies mutated code rather than the commit under review, and the fixes disappear with the workspace, so the same violations come back next run. Correction belongs in a local or pre-commit task whose output a human commits and reviews.
  • Why is detekt-formatting declared under detektPlugins rather than implementation?
    Because it contributes rules to the detekt run itself, not classes to your application. The `detektPlugins` configuration is the classpath detekt loads extra rule sets from, so it keeps the analysis dependency out of your compile and runtime classpaths entirely.

saying these in an interview costs you the question

  • Believing autoCorrect can fix a long method
  • Enabling correction on the CI verification task
  • Expecting formatting fixes without the optional rule set
  • Adding the extra rule set as a normal implementation dependency
  • Concluding autoCorrect is broken when analysis findings persist

context