airbnb/epoxy · error · IllegalStateException
Notifications already paused
Error message
Notifications already paused
What it means
ModelList.pauseNotifications is internal and idempotency-guarded: if notifications are already paused it throws IllegalStateException. This prevents double-pausing (typically two nested batchUpdate calls in Epoxy's controller/diffing machinery) from unbalancing pause/resume pairs.
Solutions
- Ensure pause/resume are strictly paired (pause once, resume once)
- Avoid calling setModels or mutating the list from inside change notifications
- Synchronize list updates to a single thread
- Do not call internal ModelList.pauseNotifications from app code
Example fix
// before
list.pauseNotifications();
list.pauseNotifications(); // throws
// after
if (!isPaused()) { list.pauseNotifications(); }
try { /* mutate */ } finally { list.resumeNotifications(); } Defensive patterns
Strategy: try-catch
Try / catch
try { list.pauseNotifications(); } catch (IllegalStateException e) { Log.w(TAG, "already paused", e); } Prevention
- Pair every pause with exactly one resume in try/finally
- Never call internal ModelList methods from app code
- Avoid re-entrant setModels from notification callbacks
- Keep list mutations on a single thread
When it happens
Trigger: Calling pauseNotifications() when notificationsPaused is already true — usually two overlapping batch updates on the same ModelList.
Common situations: Re-entrant model builds/updates (setModels called inside a notification callback); concurrent threads touching the same controller's model list; misuse of internal APIs.
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 resumed
- 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/4e6b1bba6a4fc322.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/ModelList.java:39
ModelList(int expectedModelCount) {
super(expectedModelCount);
}
ModelList() {
}
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);View on GitHub (pinned to e45bd3a61f)