DrKLO/Telegram · error · IllegalArgumentException

view is not a child, cannot hide {}

Error message

view is not a child, cannot hide {}

What it means

ChildHelper manages two logical groups of child views attached to RecyclerView: visible children and hidden (cached-but-kept) children. hide() moves a view into the hidden bucket and requires that the view is currently a tracked child — verified by mCallback.indexOfChild returning a non-negative offset. A negative offset means the view is not in the LayoutManager's child list, so there is no slot to mark hidden. This typically indicates the caller (usually RecyclerView internals or a custom LayoutManager) tried to hide a view that was already removed or never added.

Source

Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/ChildHelper.java:340

    /**
     * Returns whether a View is visible to LayoutManager or not.
     *
     * @param view The child view to check. Should be a child of the Callback.
     * @return True if the View is not visible to LayoutManager
     */
    public boolean isHidden(View view) {
        return mHiddenViews.contains(view);
    }

    /**
     * Marks a child view as hidden.
     *
     * @param view The view to hide.
     */
    void hide(View view) {
        final int offset = mCallback.indexOfChild(view);
        if (offset < 0) {
            throw new IllegalArgumentException("view is not a child, cannot hide " + view);
        }
        if (DEBUG && mBucket.get(offset)) {
            throw new RuntimeException("trying to hide same view twice, how come ? " + view);
        }
        mBucket.set(offset);
        hideViewInternal(view);
        if (DEBUG) {
            Log.d(TAG, "hiding child " + view + " at offset " + offset + ", " + this);
        }
    }

    /**
     * Moves a child view from hidden list to regular list.
     * Calling this method should probably be followed by a detach, otherwise, it will suddenly
     * show up in LayoutManager's children list.
     *
     * @param view The hidden View to unhide
     */

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. In a custom LayoutManager, verify getChildCount/indexOfChild returns the view before any operation that may hide or recycle it.
  2. Avoid calling internal ChildHelper methods from app code.
  3. If you see this with stock LayoutManagers, it is usually a RecyclerView version bug or a fork modification — update the library.
  4. Ensure views are not detached twice during animations.
Defensive patterns

Strategy: validation

Validate before calling

// In a custom LayoutManager: only hide currently-attached children
void safeHide(ChildHelper helper, View v) {
    if (indexOfChild(v) < 0) return; // not attached, nothing to hide
    helper.hide(v);
}

Prevention

When it happens

Trigger: A custom LayoutManager calling recyclerView.getChildAdapterPosition then trying to hide a detached view; RecyclerView internals calling hide during recycle after the view was already detached; a double-detach race during predictive animations; calling removeView followed by hide on the same view.

Common situations: A custom LayoutManager that does not track its attached children correctly; item animation conflict where a view is removed from the layout before the recycler tries to stash it; a view leak where the same View instance is reused across RecyclerViews.

Related errors


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