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

  1. Change the model attribute to a standard supported type (class, parameterized, array, type variable, or wildcard).
  2. Add a mapping branch for the missing JavaTypeName subtype in PoetExtensions.kt's toKPoet when block.
  3. Pin/align JavaPoet versions so no unexpected new TypeName subtype reaches the converter.
  4. 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

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


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)