airbnb/epoxy · error · IllegalStateException
Model is not added
Error message
Model is not added: {model} What it means
getAllModelsAfter(model) requires the given model to exist in the models list (documented via @param model Must exist in {@link #models}). When getModelPosition(model) returns -1 the sublist cannot be computed, so an IllegalStateException "Model is not added" is thrown.
Solutions
- Verify the anchor model is present (getModelPosition(model) != -1) before calling
- Ensure the anchor model is added unconditionally or guard the call behind the same condition that adds it
- Re-acquire the model reference from the adapter instead of holding stale instances across updates
Example fix
// before
adapter.hideAllAfterModel(myHeader);
// after
if (adapter.getModelPosition(myHeader) != -1) {
adapter.hideAllAfterModel(myHeader);
} Defensive patterns
Strategy: validation
Validate before calling
if (adapter.getModelPosition(model) != -1) { List<EpoxyModel<?>> after = adapter.getAllModelsAfter(model); } Try / catch
try { adapter.hideAllAfterModel(model); } catch (IllegalStateException e) { /* anchor missing; skip or rebuild list */ } Prevention
- Only call hideAllAfterModel/getAllModelsAfter with models added unconditionally
- Re-fetch model instances from the adapter after list rebuilds instead of caching
When it happens
Trigger: Calling getAllModelsAfter (directly, or via hideAllAfterModel/modelsToRemove) with a model that is not currently in the adapter's models list.
Common situations: hideAllAfterModel on a model that was conditionally not added; a stale model reference after a clearModels(); diffing-based updates removing the anchor before the helper runs.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Model is not added
- Model is not added
- You must enable diffing before notifying models changed
- You cannot call `buildModels` directly. Call `setData`…
- You cannot call `requestModelBuild` directly. Call…
AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13).
Data as JSON: /api/errors/9549e3fe3b487047.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAdapter.java:342
* Hides all models currently located after the given model in the {@link #models} list.
*
* @param model The model after which to hide. It must exist in the {@link #models} list.
*/
protected void hideAllAfterModel(EpoxyModel<?> model) {
hideModels(getAllModelsAfter(model));
}
/**
* Returns a sub list of all items in {@link #models} that occur after the given model. This list
* is backed by the original models list, any changes to the returned list will be reflected in
* the original {@link #models} list.
*
* @param model Must exist in {@link #models}.
*/
protected List<EpoxyModel<?>> getAllModelsAfter(EpoxyModel<?> model) {
int index = getModelPosition(model);
if (index == -1) {
throw new IllegalStateException("Model is not added: " + model);
}
return models.subList(index + 1, models.size());
}
/**
* We pause the list's notifications when we modify models internally, since we already do the
* proper adapter notifications for those modifications. By pausing these list notifications we
* prevent the differ having to do work to track them.
*/
private void pauseModelListNotifications() {
((ModelList) models).pauseNotifications();
}
private void resumeModelListNotifications() {
((ModelList) models).resumeNotifications();
}
}
View on GitHub (pinned to e45bd3a61f)