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

  1. Read the custom message to identify the offending API, then defer it to a layout-valid moment.
  2. Post the operation to the next frame: recyclerView.post(() -> recyclerView.removeItemDecoration(d)).
  3. 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

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


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/ef0a5b5c68cb49d7. Report an issue: GitHub.