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
- One symbol, IDE offers an import → missing import. Accept it.
- A whole library unresolved → missing or mis-scoped dependency. Fix
build.gradleand sync. - It's
R,BuildConfig, a Binding, or a DAO → generated code. Build the project. - It's clearly declared and still red → stale sync. Sync, then invalidate caches if needed.
Package and library names above are placeholders — use your own.