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
- 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)
- If you construct AttributeGroup in custom code, only pass a defaultAttribute after verifying codeToSetDefault is not empty or hasDefaultKotlinValue is true
- 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
- Give default attributes explicit Kotlin default values (var x: T = default)
- Don't mark attributes with types/setters the processor cannot render as defaults
- Only designate a default attribute when its default-setting code is verifiably non-empty
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
- Attributes cannot be empty
- Nullability has not been set
- Failed to create regex for resource reference…
- Please use value or code explicitly
- You must set an id on a model before adding it. Use the…
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)