airbnb/epoxy · error · IllegalArgumentException
Unsupported type
Error message
Unsupported type: ${this::class.simpleName} What it means
This KotlinPoet conversion helper maps JavaPoet type names (JavaTypeName variants) to KotlinPoet types via exhaustive when branches. If a JavaTypeName subtype is encountered that has no mapping branch, toKPoet throws this IllegalArgumentException, indicating an unmapped/unknown type-name kind reached the converter.
Solutions
- Change the model attribute to a standard supported type (class, parameterized, array, type variable, or wildcard).
- Add a mapping branch for the missing JavaTypeName subtype in PoetExtensions.kt's toKPoet when block.
- Pin/align JavaPoet versions so no unexpected new TypeName subtype reaches the converter.
- Log the full type in a reproducer and file an issue upstream with the concrete type name.
Example fix
// before val attr: SomeExoticType = ... // JavaTypeName subtype with no mapping // after val attr: SomeSupportedType = ... // e.g. a ClassName/ParametrizedTypeName-backed type
Defensive patterns
Strategy: try-catch
Type guard
fun isSupportedJavaTypeName(t: JavaTypeName) = t is JavaClassName || t is JavaParametrizedTypeName || t is JavaArrayTypeName || t is JavaTypeVariableName || t is JavaWildcardTypeName || t == JavaTypeName.VOID
Try / catch
try {
val kotlinType = typeName.toKPoet(nullable = false)
} catch (e: IllegalArgumentException) {
if (e.message?.startsWith("Unsupported type:") == true) {
throw IllegalStateException("Unmapped JavaTypeName in codegen: ${typeName}", e)
} else throw e
} Prevention
- Restrict model attribute types to standard class/parameterized/array types.
- When upgrading JavaPoet, review toKPoet's when for newly introduced subtypes.
- Add a processor test covering every TypeName kind your models use.
When it happens
Trigger: Converting a generated-attribute type whose JavaTypeName is none of VOID, ClassName, ParametrizedTypeName, ArrayTypeName, TypeVariableName, or WildcardTypeName — e.g. a primitive-special or new JavaPoet subtype introduced by an upstream library version.
Common situations: Model attributes with unusual types (newer JavaPoet types, exotic generics) fed into Epoxy's Kotlin code generation; upgrading JavaPoet/annotation-tool versions introducing a new TypeName subtype; custom processor code constructing an unmapped TypeName subclass.
Related errors
- Room couldn't find the constructor it is looking for in…
- Nullability has not been set
- Expected this to be a variable or method $this
- Must have stable ids when saving view holder state
- State cannot be restored once views have been bound. It…
AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13).
Data as JSON: /api/errors/fda66276e547f6e4.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-processor/src/main/java/com/airbnb/epoxy/processor/PoetExtensions.kt:192
fun JavaTypeName.toKPoet(nullable: Boolean = false): KotlinTypeName {
val type = when (this) {
JavaTypeName.BOOLEAN -> BOOLEAN
JavaTypeName.BYTE -> BYTE
JavaTypeName.SHORT -> SHORT
JavaTypeName.CHAR -> CHAR
JavaTypeName.INT -> INT
JavaTypeName.LONG -> LONG
JavaTypeName.FLOAT -> FLOAT
JavaTypeName.DOUBLE -> DOUBLE
JavaTypeName.OBJECT -> ANY
JavaTypeName.VOID -> UNIT
is JavaClassName -> toKPoet()
is JavaParametrizedTypeName -> toKPoet()
is JavaArrayTypeName -> toKPoet()
is JavaTypeVariableName -> toKPoet()
is JavaWildcardTypeName -> toKPoet()
else -> throw IllegalArgumentException("Unsupported type: ${this::class.simpleName}")
}
if (nullable) {
return type.copy(nullable = true)
}
return type
}
fun <T : JavaTypeName> Iterable<T>.toKPoet() = map { it.toKPoet() }
fun JavaParameterSpec.toKPoet(): KotlinParameterSpec {
// A param name in java might be reserved in kotlin
val paramName = if (name in KOTLIN_KEYWORDS) name + "Param" else name
val nullable = annotations.any { (it.type as? JavaClassName)?.simpleName() == "Nullable" }
View on GitHub (pinned to e45bd3a61f)