skip to content

What does the kapt correctErrorTypes option do, and when do you need to enable it?

level: seniorimportance: should knowfreq 40%

answer

  1. Fixes NonExistentClass placeholder for not-yet-generated types
  2. kapt { correctErrorTypes = true }
  3. Off by default for performance
  4. Needed for Dagger + Room/Moshi cross-codegen
  5. Records then substitutes the real type back

basics

~20 s

correctErrorTypes tells kapt to recover the real types of code that is itself still being generated. Without it, those types show up as a meaningless 'error' placeholder and processors break. It is off by default.

solid answer

~50 s

`correctErrorTypes` is a kapt flag (set in the `kapt { }` block) that handles **error types** in stubs. When stub generation runs, some referenced types may not exist yet — typically because they are produced by *another* annotation processor in the same round (e.g. Dagger references a Room-generated DAO, or generated `_Factory`/`_Impl` classes). In Java's processing model such unresolved references become `ErrorType` and kapt, by default, replaces them with the placeholder `NonExistentClass`, which corrupts the processor's view and causes failures like wrong types in generated bindings. With `correctErrorTypes = true`, kapt **infers and substitutes the correct types** by recording the original type names and patching them back after processing, so downstream processors see the intended types. It is **disabled by default** for performance, and the canonical case to turn it on is **Dagger + another codegen processor** (or any cross-processor generated-type dependency). Set it via `kapt { correctErrorTypes = true }`.

code

kotlin · 15 lines
kotlin
// build.gradle.kts
plugins {
    kotlin("jvm")
    kotlin("kapt")
}

kapt {
    // Needed when Dagger references types generated by Room/Moshi etc.
    correctErrorTypes = true
}

dependencies {
    kapt("com.google.dagger:dagger-compiler:2.51")
    kapt("androidx.room:room-compiler:2.6.1")
}

go deeper

for a junior

May only know it's a kapt setting you sometimes turn on for Dagger.

for a middle

Knows it resolves generated types that don't exist yet and is set in the kapt block.

for a senior

Explains the ErrorType/NonExistentClass mechanism, why it's off by default, and the Dagger+Room scenario that requires it.

for a principal

Can diagnose a NonExistentClass build failure from logs and reason about processor ordering/cross-codegen dependencies that force the flag.

## The problem: error types in stubs When kapt generates Java **stubs**, every referenced type must resolve to a Java `Element`. But during a build, some types **don't exist yet** — they are *about to be generated* by an annotation processor in the same compilation. Examples: - A Dagger `@Module` that provides a Room database, whose `*_Impl`/DAO classes Room generates. - A class that references a `*_Factory`, `*_MembersInjector`, or other codegen output. In the Java model, an unresolved reference is an **`ErrorType`** (`javax.lang.model.type.ErrorType`). kapt's default behavior is to write such a reference into the stub as the placeholder class **`NonExistentClass`**. Any processor reading that stub now sees `NonExistentClass` instead of the real (soon-to-exist) type, producing broken generated code or confusing errors. ## What correctErrorTypes does Enabling it changes how kapt handles those error types: ```kotlin // build.gradle.kts kapt { correctErrorTypes = true } ``` With the flag on, kapt: 1. **Records the original, intended type name** for each reference that resolves to an error type during stub generation. 2. After processors run and the real types come into existence, **substitutes the correct type back** in place of `NonExistentClass`, so the generated/processed code references the proper type. In effect it lets kapt *recover* types that are only known after a later processing round, rather than freezing them as a broken placeholder. ## When to enable it - **Default is `false`** (it adds work, so it's off for performance). - Turn it on whenever **one processor's output is consumed by another processor** in the same module — the textbook case is **Dagger/Hilt combined with Room, Moshi-codegen, AutoValue,** or similar. The classic symptom without it: Dagger errors referencing `error.NonExistentClass` or `NonExistentClass` in a generated component. ## How to recognize the need in an interview/codebase - Build error text contains `NonExistentClass` or `error.NonExistentClass`. - You mix two codegen processors via kapt where one depends on the other's generated types. ## Keywords `kapt { correctErrorTypes = true }`, `ErrorType`, `NonExistentClass`, cross-processor generated types, Dagger + Room.

  • What placeholder does kapt use when correctErrorTypes is disabled and a type is unresolved?
    It substitutes `NonExistentClass` (often surfaced as `error.NonExistentClass`) for the error type, which is what breaks downstream processors.
  • Why isn't correctErrorTypes simply on by default?
    Recording and re-substituting error types adds processing overhead, so kapt leaves it off and asks you to opt in only when you have cross-processor generated-type dependencies.

It's a 'fill in the blank later' note: kapt writes a placeholder for a type that doesn't exist yet, then comes back and pencils in the real name once it's generated.

saying these in an interview costs you the question

  • Saying correctErrorTypes fixes general compile errors in your own Kotlin code (it only handles generated/error types)
  • Claiming it is enabled by default
  • Not connecting it to the NonExistentClass placeholder
  • Thinking it relates to KSP (it is purely a kapt stub concern)

context