airbnb/epoxy · error · IllegalStateException
Notifications already resumed
Error message
Notifications already resumed
What it means
This IllegalStateException is a symmetric state guard in ModelList.resumeNotifications. The class tracks pause/resume of change notifications with a boolean flag; resumeNotifications is only valid when notifications are currently paused. It throws when called while notificationsPaused is false — i.e. resumeNotifications() was called without a prior, still-active pauseNotifications() call (never paused, or already resumed). The source block shows a generic boolean state guard, so the faulting input is the invalid call sequence: a second resumeNotifications() after notifications were already resumed, or a resume with no matching pause. Callers should pair every pauseNotifications()/resumeNotifications() in balanced, non-reentrant blocks (e.g. begin/end or try/finally around batch mutations).
Solutions
- Wrap mutations so resume is only called once per successful pause
- Track pause state in app code or use a boolean guard before resuming
- Avoid calling internal ModelList.resumeNotifications directly
- Fix exceptions thrown between pause and resume so the pair stays balanced
Example fix
// before
list.resumeNotifications(); // may throw if not paused
// after
if (paused) {
list.resumeNotifications();
paused = false;
} Defensive patterns
Strategy: try-catch
Try / catch
try { list.resumeNotifications(); } catch (IllegalStateException e) { Log.w(TAG, "not paused", e); } Prevention
- Only resume after a successful pause
- Use try/finally so exceptions don't leave the list in a paused state
- Track pause state locally before calling resume
- Don't call internal APIs from application code
When it happens
Trigger: Calling resumeNotifications() when notificationsPaused is false (never paused, or already resumed).
Common situations: Unbalanced try/finally around list mutations; resuming after an exception already resumed the list; calling internal API from app code.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Notifications already paused
- Cannot call `requestModelBuild` from inside `buildModels`
- Cannot call `requestDelayedModelBuild` from inside…
- Must have stable ids when saving view holder state
- State cannot be restored once views have been bound. It…
AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13).
Data as JSON: /api/errors/45ff2436fd4ca56e.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelList.java:46
interface ModelListObserver {
void onItemRangeInserted(int positionStart, int itemCount);
void onItemRangeRemoved(int positionStart, int itemCount);
}
private boolean notificationsPaused;
private ModelListObserver observer;
void pauseNotifications() {
if (notificationsPaused) {
throw new IllegalStateException("Notifications already paused");
}
notificationsPaused = true;
}
void resumeNotifications() {
if (!notificationsPaused) {
throw new IllegalStateException("Notifications already resumed");
}
notificationsPaused = false;
}
void setObserver(ModelListObserver observer) {
this.observer = observer;
}
private void notifyInsertion(int positionStart, int itemCount) {
if (!notificationsPaused && observer != null) {
observer.onItemRangeInserted(positionStart, itemCount);
}
}
private void notifyRemoval(int positionStart, int itemCount) {
if (!notificationsPaused && observer != null) {
observer.onItemRangeRemoved(positionStart, itemCount);
}View on GitHub (pinned to e45bd3a61f)