airbnb/epoxy · error · EpoxyProcessorException

Default attribute has no default code

Error message

Default attribute has no default code

What it means

GeneratedModelInfo.AttributeGroup requires that when a default attribute is designated, the processor can emit code to set it: either codeToSetDefault is non-empty or the attribute has a Kotlin default value (checked by hasDefaultKotlinValue). If a default attribute is set but carries no default-setting code, the processor throws 'Default attribute has no default code' to prevent generating models that cannot apply the default. Reached from addAttributeGroup.

Solutions

  1. Ensure the default attribute is one the processor can set: give it a type with straightforward setter code, or declare a Kotlin default value in the @EpoxyAttribute (e.g. `var title: String = ""`) If the attribute should not be a default, remove it as the designated default so the group just becomes required (isRequired = true)
  2. If you construct AttributeGroup in custom code, only pass a defaultAttribute after verifying codeToSetDefault is not empty or hasDefaultKotlinValue is true
  3. Report/bisect against the Epoxy processor version if a plain annotated attribute triggers this

Example fix

// before
@EpoxyAttribute var title: String? = null // designated default, but no default code generated
// after
@EpoxyAttribute var title: String = "" // Kotlin default value -> hasDefaultKotlinValue true
Defensive patterns

Strategy: validation

Validate before calling

// caller-side check before designating a default
val canBeDefault = attribute.codeToSetDefault.isNotEmpty // or attribute has Kotlin default value
if (defaultCandidate != null && !canBeDefault) {
    error("Default attribute '${defaultCandidate.name}' has no default code")
}

Prevention

When it happens

Trigger: AttributeGroup is constructed with a non-null defaultAttribute whose codeToSetDefault is empty and which has no Kotlin default value — i.e. an attribute was marked as the group default but the processor could not derive any code to assign it.

Common situations: Model attributes with exotic types or custom setters that the processor cannot render default code for; attributes introduced via custom processor extensions; Kotlin/Java mixed models where default detection fails; Epoxy version upgrades changing default-code generation.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13). Data as JSON: /api/errors/00dcf18068556871. Report an issue: GitHub.

Appendix: source

Thrown at epoxy-processor/src/main/java/com/airbnb/epoxy/processor/GeneratedModelInfo.kt:266

    class AttributeGroup internal constructor(
        groupName: String?,
        attributes: List<AttributeInfo>,
        defaultAttribute: AttributeInfo?
    ) {
        val name: String?
        val attributes: List<AttributeInfo>
        val isRequired: Boolean
        val defaultAttribute: AttributeInfo?

        init {
            if (attributes.isEmpty()) {
                throw buildEpoxyException("Attributes cannot be empty")
            }
            if (defaultAttribute != null && defaultAttribute.codeToSetDefault.isEmpty &&
                !hasDefaultKotlinValue(defaultAttribute)
            ) {
                throw buildEpoxyException("Default attribute has no default code")
            }
            this.defaultAttribute = defaultAttribute
            isRequired = defaultAttribute == null
            name = groupName
            this.attributes =
                ArrayList(attributes)
        }
    }

    companion object {
        const val RESET_METHOD = "reset"
        const val GENERATED_CLASS_NAME_SUFFIX = "_"
        const val GENERATED_MODEL_SUFFIX = "Model$GENERATED_CLASS_NAME_SUFFIX"

        fun buildParamSpecs(params: List<XVariableElement>, memoizer: Memoizer): List<ParameterSpec> {
            return params.map { it.toParameterSpec(memoizer) }
        }

View on GitHub (pinned to e45bd3a61f)