Debugging log · Build
"Program type already present" during dexing
Late in the build — during dexing, the step that turns compiled classes into the format Android runs — it stopped with Program type already present and a class name. The message is blunt: this exact class showed up twice, and the dexer can't put two copies of the same type into the app. It's a close cousin of the "Duplicate class" compile error, arriving at a later stage.
The short version: two things on your classpath contain the same class. Usually one dependency bundles a library that another also pulls in, or you've added the same library under two different coordinates. Find the two sources and exclude or align one.
The error
Program type already present: com.example.util.Foo ... com.android.tools.r8.errors...
The class name is the thread to pull. Search your dependency graph for who provides com.example.util.Foo, and you'll almost always find two answers.
Why it happens at dex time
By the time dexing runs, everything has compiled and the tool is merging all classes into the app's dex files. If the same fully-qualified class arrives from two paths, there's no way to keep both — they'd occupy the same slot. Two common shapes: a library that embeds (fat-jars) another library you also depend on directly, or the same artifact pulled in under an old and a new coordinate (a renamed group, or a support-library class that also exists in AndroidX).
Find the two sources
Print the dependency tree and search for the class's library:
./gradlew app:dependencies --configuration releaseRuntimeClasspath
Look for the same package appearing under two different parents. Those two parents are what you'll reconcile. If the class is something generic (a JSON or annotations helper), the culprit is often a heavy SDK that bundled its own copy instead of depending on it cleanly.
Fix 1 — exclude the bundled copy
If one dependency drags in a duplicate you already get elsewhere, exclude it there:
implementation("com.example:big-sdk:2.0.0") {
exclude(group = "com.example", module = "util")
}
Now only one copy of util survives. This is the right move when a bulky SDK re-bundles a common library.
Fix 2 — align to one version/coordinate
If both dependencies legitimately need the library but pull different versions or coordinates, force a single one so only one artifact resolves:
configurations.all {
resolutionStrategy {
force("com.example:util:1.5.0")
}
}
Fix 3 — the AndroidX / support-library case
If the duplicated class is an android.support.* type clashing with its androidx.* equivalent, don't exclude class by class — that's a losing game. Make sure the whole project is on AndroidX:
# gradle.properties android.useAndroidX=true android.enableJetifier=true
Then remove or update the last dependency still bringing in old support-library artifacts.
This is the same root cause as the compile-time "Duplicate class" error, just caught at a different stage. If you've read that write-up, the toolkit is identical: dependency tree, then exclude or force. The class name in the message is always where to start.
Confirming the fix
- Re-run the dependencies report and check the library now resolves to a single artifact.
- Clean and rebuild — dexing works on merged output, so stale artifacts can keep reporting the old clash.
- Change one exclude or force at a time so you know which one resolved it.
Class, group and module names above are placeholders — target the exact class in your own error.