DrKLO/Telegram · error · IllegalArgumentException

Called removeDetachedView with a view which is not flagged a

Error message

Called removeDetachedView with a view which is not flagged as tmp detached.{vh}

What it means

RecyclerView.removeDetachedView overrides ViewGroup.removeDetachedView and asserts that a child being removed is either marked as temporarily detached (vh.isTmpDetached()) or explicitly flagged to ignore (shouldIgnore()). If neither holds, it throws IllegalArgumentException. The temporary-detach flag is an internal invariant RecyclerView sets when it briefly detaches a view during scrap/recycle bookkeeping; an externally-removed view lacking that flag indicates the detach protocol was bypassed, which would corrupt recycling state.

Source

Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java:4349

        }
        into[0] = minPositionPreLayout;
        into[1] = maxPositionPreLayout;
    }

    private boolean didChildRangeChange(int minPositionPreLayout, int maxPositionPreLayout) {
        findMinMaxChildLayoutPositions(mMinMaxLayoutPositions);
        return mMinMaxLayoutPositions[0] != minPositionPreLayout
                || mMinMaxLayoutPositions[1] != maxPositionPreLayout;
    }

    @Override
    protected void removeDetachedView(View child, boolean animate) {
        ViewHolder vh = getChildViewHolderInt(child);
        if (vh != null) {
            if (vh.isTmpDetached()) {
                vh.clearTmpDetachFlag();
            } else if (!vh.shouldIgnore()) {
                throw new IllegalArgumentException("Called removeDetachedView with a view which"
                        + " is not flagged as tmp detached." + vh + exceptionLabel());
            }
        }

        // Clear any android.view.animation.Animation that may prevent the item from
        // detaching when being removed. If a child is re-added before the
        // lazy detach occurs, it will receive invalid attach/detach sequencing.
        child.clearAnimation();

        dispatchChildDetached(child);
        super.removeDetachedView(child, animate);
    }

    /**
     * Returns a unique key to be used while handling change animations.
     * It might be child's position or stable id depending on the adapter type.
     */
    long getChangedHolderKey(ViewHolder holder) {

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Do not call removeView/removeDetachedView on RecyclerView children directly — use the LayoutManager (removeAndRecycleView / removeAndRecycleViewAt) or let RecyclerView manage its own children.
  2. Audit any custom LayoutManager to ensure it only detaches views via LayoutManager.detachViewAt (which sets the tmp-detach flag) and reattaches before layout completes.
  3. If a third-party animation/container library manipulates RecyclerView children, replace it with an ItemAnimator or wrap the manipulation so it sets the proper flags.
  4. Update androidx.recyclerview to the latest stable version — several historical regressions in detach bookkeeping have been fixed upstream.

Example fix

// before: manually removing a RecyclerView child
View child = recyclerView.getChildAt(0);
recyclerView.removeView(child); // bypasses detach protocol -> throw
// after: let the layout/recycler handle it, or the LM
recyclerView.getLayoutManager().removeAndRecycleViewAt(0, recycler);
Defensive patterns

Strategy: validation

Validate before calling

// Do not validate around this; instead avoid the API entirely.
// Ensure children are only removed via the LayoutManager/Recycler:
if (layoutManager != null) {
  layoutManager.removeAndRecycleViewAt(index, recycler);
}

Prevention

When it happens

Trigger: Externally calling ViewGroup.removeView / removeDetachedView on a RecyclerView child instead of going through the LayoutManager/Recycler API; a LayoutManager that manually detaches views without the tmp-detach flag and then RecyclerView later tries to remove them; nested RecyclerView or nested scrolling components that reach into the parent's view tree.

Common situations: Mixing manual ViewGroup view manipulation with RecyclerView; a third-party container or animation library that pulls views out of the RecyclerView; a custom LayoutManager misusing addDisappearingView/scrap attach calls; very old appcompat or RecyclerView version with a known regression on this path.

Related errors


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