DrKLO/Telegram · error · IllegalStateException
Cannot call this method while RecyclerView is computing a la
Error message
Cannot call this method while RecyclerView is computing a layout or scrolling
What it means
assertNotInLayoutOrScroll(null) is the inverse guard: it forbids methods that must NOT run during a layout or scroll pass (e.g. setAdapter, setLayoutManager, setHasFixedSize, adapter data-set calls that re-trigger layout). If isComputingLayout() is true and no message was supplied, it throws 'Cannot call this method while RecyclerView is computing a layout or scrolling'. Re-entrant layout mutations corrupt the in-flight pass.
Source
Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java:3057
throw new IllegalStateException("Cannot call this method unless RecyclerView is "
+ "computing a layout or scrolling" + exceptionLabel());
}
throw new IllegalStateException(message + exceptionLabel());
}
}
/**
* Checks if RecyclerView is in the middle of a layout or scroll and throws an
* {@link IllegalStateException} if it <b>is</b>.
*
* @param message The message for the exception. Can be null.
* @see #assertInLayoutOrScroll(String)
*/
void assertNotInLayoutOrScroll(String message) {
if (isComputingLayout()) {
if (message == null) {
throw new IllegalStateException("Cannot call this method while RecyclerView is "
+ "computing a layout or scrolling" + exceptionLabel());
}
throw new IllegalStateException(message);
}
if (mDispatchScrollCounter > 0) {
Log.w(TAG, "Cannot call this method in a scroll callback. Scroll callbacks might"
+ "be run during a measure & layout pass where you cannot change the"
+ "RecyclerView data. Any method call that might change the structure"
+ "of the RecyclerView or the adapter contents should be postponed to"
+ "the next frame.",
new IllegalStateException("" + exceptionLabel()));
}
}
/**
* Add an {@link OnItemTouchListener} to intercept touch events before they are dispatched
* to child views or this view's standard scrolling behavior.
*View on GitHub (pinned to 45ab8f4308)
Solutions
- Defer structural changes out of the layout/scroll pass: use recyclerView.post(() -> adapter.notifyDataSetChanged()).
- For pagination, set a pending flag in onScrolled and apply new data on the next frame.
- Never call setAdapter/setLayoutManager from within onLayoutChildren or ItemDecoration callbacks.
Example fix
// before
recyclerView.addOnScrollListener(new OnScrollListener() {
@Override public void onScrolled(RecyclerView rv, int dx, int dy) {
if (atBottom) adapter.loadMore(); // may call notify* during layout
}
});
// after
recyclerView.addOnScrollListener(new OnScrollListener() {
@Override public void onScrolled(RecyclerView rv, int dx, int dy) {
if (atBottom && !pendingLoad) {
pendingLoad = true;
rv.post(() -> { adapter.loadMore(); pendingLoad = false; });
}
}
}); Defensive patterns
Strategy: validation
Validate before calling
Runnable structuralChange = () -> {
adapter.notifyDataSetChanged(); // or setAdapter / setLayoutManager
};
if (recyclerView.isComputingLayout()) {
recyclerView.post(structuralChange);
} else {
structuralChange.run();
} Type guard
null
Try / catch
null
Prevention
- Never call setAdapter/setLayoutManager/notifyDataSetChanged from within onLayoutChildren or scroll listeners.
- Defer pagination loads with a pending flag and apply on the next frame.
- Assert !isComputingLayout() in debug builds before structural mutations.
When it happens
Trigger: Calling setAdapter, swapAdapter, setLayoutManager, or adapter.notify* from inside onLayoutChildren of a custom LayoutManager, from an ItemDecoration.onDraw, or from a scroll listener that triggers a data mutation.
Common situations: Adapter swap triggered inside a scroll listener (onScrolled) that itself runs during layout. Custom LayoutManager that calls recyclerView.setAdapter during layout. Infinite scroll that calls notifyDataSetChanged synchronously inside onScrolled.
Related errors
- Cannot call this method unless RecyclerView is computing a l
- {message}
- Called attach on a child which is not detached: {vh}
- called detach on an already detached child {vh}
- LayoutManager {layout} is already attached to a RecyclerView
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/bb654b8faa34397c.
Report an issue: GitHub.