airbnb/epoxy · error · EpoxyProcessorException
Attributes cannot be empty
Error message
Attributes cannot be empty
What it means
GeneratedModelInfo.AttributeGroup is an internal processor invariant: every attribute group must contain at least one AttributeInfo. An empty attributes list means the processor assembled a group with no attributes, indicating a bug or malformed model input, so it throws 'Attributes cannot be empty' via buildEpoxyException. Reached from addAttributeGroup while generating model info.
Solutions
- Check the model class that triggered the failure: ensure at least one attribute is actually declarable/visible to the processor (not all filtered out by annotations or visibility)
- If you build AttributeGroup in custom code, guard with require(attributes.isNotEmpty()) before constructing
- Update or bisect the Epoxy processor version — if a valid model triggers this, it is a processor bug worth reporting with a minimal reproducer
- Clear build caches / run a clean build to rule out stale generated model info
Example fix
// before (custom processor code)
addAttributeGroup(groupName, attributes)
// after
if (attributes.isNotEmpty()) {
addAttributeGroup(groupName, attributes)
} Defensive patterns
Strategy: validation
Validate before calling
// caller-side check before registering a group
require(attributes.isNotEmpty()) { "Attribute group '$groupName' has no attributes" } Prevention
- Verify your model classes expose at least one processor-visible attribute
- Skip group creation entirely when the attribute list is empty
- Run clean builds after upgrading the processor to avoid stale grouped state
When it happens
Trigger: addAttributeGroup is called (directly or via processor model parsing) with an empty List<AttributeInfo>, e.g. when a model class's attributes were all filtered out before grouping but the group was still registered.
Common situations: Custom processor extensions or forks that construct AttributeGroup manually; model classes where attribute collection logic yields nothing (e.g. all attributes excluded) but a group name is still provided; internal Epoxy processor bugs after version upgrades.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Default attribute has no default code
- 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/0e1e6e9a96c6a9b5.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-processor/src/main/java/com/airbnb/epoxy/processor/GeneratedModelInfo.kt:261
}
fun attributeGroup(attribute: AttributeInfo): AttributeGroup? {
return attributeToGroup[attribute]
}
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"View on GitHub (pinned to e45bd3a61f)