DrKLO/Telegram · error · IllegalStateException
{message}
Error message
{message} What it means
The same assertInLayoutOrScroll method, but called WITH a custom message. When isComputingLayout() is false, it throws IllegalStateException(message + exceptionLabel()). The custom message lets the call site identify which API was misused (e.g. 'Cannot remove item decoration during layout'). The semantics are identical to the null-message variant: the call must occur within the layout/scroll window.
Source
Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java:3042
@Override
public boolean isAttachedToWindow() {
return mIsAttached;
}
/**
* Checks if RecyclerView is in the middle of a layout or scroll and throws an
* {@link IllegalStateException} if it <b>is not</b>.
*
* @param message The message for the exception. Can be null.
* @see #assertNotInLayoutOrScroll(String)
*/
void assertInLayoutOrScroll(String message) {
if (!isComputingLayout()) {
if (message == null) {
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);View on GitHub (pinned to 45ab8f4308)
Solutions
- Read the custom message to identify the offending API, then defer it to a layout-valid moment.
- Post the operation to the next frame: recyclerView.post(() -> recyclerView.removeItemDecoration(d)).
- For adapter mutations, use notifyItem* on the main thread after data is set, not during scroll callbacks that mutate structure.
Example fix
// before button.setOnClickListener(v -> recyclerView.removeItemDecoration(divider)); // after button.setOnClickListener(v -> recyclerView.post(() -> recyclerView.removeItemDecoration(divider)));
Defensive patterns
Strategy: validation
Validate before calling
Runnable remove = () -> recyclerView.removeItemDecoration(divider);
if (recyclerView.isComputingLayout()) {
recyclerView.post(remove);
} else {
remove.run();
} Type guard
null
Try / catch
null
Prevention
- Read the custom message to identify the offending API, then defer it out of the layout pass.
- Use recyclerView.post for any structural mutation triggered by user input.
- Keep ItemDecoration add/remove out of scroll and layout callbacks.
When it happens
Trigger: Any of dozens of RecyclerView APIs that pass a specific message to assertInLayoutOrScroll — e.g. removeItemDecoration, addItemDecoration, certain adapter mutations — invoked outside the layout/scroll pass.
Common situations: Removing an ItemDecoration from a button click (outside layout). Mutating adapter data from a background thread callback that lands outside the layout window. Calling requestLayout-forcing APIs during a scroll callback incorrectly.
Related errors
- Cannot call this method unless RecyclerView is computing a l
- Cannot call this method while RecyclerView is computing a la
- should not dispatch add or move for pre layout
- op should be remove or update.{}
- Called attach on a child which is not detached: {vh}
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/ef0a5b5c68cb49d7.
Report an issue: GitHub.