Mr.AndroidShin / Dev Tools

Debugging log · Kotlin

"Unresolved reference" — when it isn't a typo

Kotlin underlines a name in red and calls it an unresolved reference, but you can see the class or function right there, spelled correctly. When it's genuinely not a typo, the compiler is telling you it can't find the thing from where you're standing — and there are four everyday reasons for that, each with a different fix.

The short version: the name exists, but it isn't visible here. Either you haven't imported it, the dependency that provides it isn't on your classpath, it's generated code that hasn't been built yet, or your IDE is working from a stale sync. Work through those four and it resolves.

The error

e: Example.kt: (12, 9): Unresolved reference: SomeClass

Cause 1 — a missing import

The most common non-typo cause. The class exists in another package and you simply haven't imported it. In the editor, put the cursor on the red name and let it offer the import (Alt+Enter). If nothing is offered, that's a clue the problem is deeper — the symbol isn't on the classpath at all, which points at the next cause.

Cause 2 — a missing (or wrong) dependency

If a whole library's classes are unresolved, the dependency that provides them isn't declared, or was declared in the wrong scope or module. Check your module's build.gradle:

dependencies {
    implementation("com.example:some-library:1.0.0")
}

Watch for scope mistakes: something added only to the test configuration won't resolve in main code, and a dependency added to the wrong module in a multi-module project won't be visible where you're using it. After adding it, sync Gradle so the classpath updates.

Cause 3 — generated code that hasn't been built

This one fools everyone. Some references only exist after a build generates them: BuildConfig, R, View Binding classes, and code from annotation processors (Room, Hilt, and similar). On a fresh checkout or after a clean, these don't exist yet, so the editor flags them as unresolved even though your code is correct. The fix is to build:

./gradlew assembleDebug

Once the generated sources exist, the references resolve. If a Binding or a Room DAO is unresolved specifically, it's almost always this — build first, judge later.

Cause 4 — a stale IDE / Gradle sync

Sometimes everything is declared correctly and the IDE just hasn't caught up. Its model of your project is out of date, so it can't see a dependency or generated class that really is there. Trigger a Sync Project with Gradle Files, and if that doesn't clear it, invalidate caches and restart. This is the "I changed nothing and it broke" case, and a sync is the reset button.

Order matters: check the import first (cheap), then the dependency, then build to generate code, then sync. Jumping straight to "invalidate caches" works often enough that people do it reflexively — but it hides which of the real causes it was, so you learn nothing for next time.

A quick decision guide

Package and library names above are placeholders — use your own.