DrKLO/Telegram · error · IllegalArgumentException

LayoutManager {layout} is already attached to a RecyclerView

Error message

LayoutManager {layout} is already attached to a RecyclerView:{recyclerView}

What it means

setLayoutManager checks layout.mRecyclerView before binding. A LayoutManager may be attached to at most ONE RecyclerView; if it is already bound, attaching it again throws 'LayoutManager is already attached to a RecyclerView'. A LayoutManager holds per-RecyclerView state (recycler, view, animations) that cannot be shared.

Source

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

            }
            mLayout.removeAndRecycleAllViews(mRecycler);
            mLayout.removeAndRecycleScrapInt(mRecycler);
            mRecycler.clear();

            if (mIsAttached) {
                mLayout.dispatchDetachedFromWindow(this, mRecycler);
            }
            mLayout.setRecyclerView(null);
            mLayout = null;
        } else {
            mRecycler.clear();
        }
        // this is just a defensive measure for faulty item animators.
        mChildHelper.removeAllViewsUnfiltered();
        mLayout = layout;
        if (layout != null) {
            if (layout.mRecyclerView != null) {
                throw new IllegalArgumentException("LayoutManager " + layout
                        + " is already attached to a RecyclerView:"
                        + layout.mRecyclerView.exceptionLabel());
            }
            mLayout.setRecyclerView(this);
            if (mIsAttached) {
                mLayout.dispatchAttachedToWindow(this);
            }
        }
        mRecycler.updateViewCacheSize();
        requestLayout();
    }

    /**
     * Set a {@link OnFlingListener} for this {@link RecyclerView}.
     * <p>
     * If the {@link OnFlingListener} is set then it will receive
     * calls to {@link #fling(int,int)} and will be able to intercept them.
     *

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Create a new LayoutManager instance per RecyclerView; do not share instances.
  2. If reusing programmatically, first call oldRecyclerView.setLayoutManager(null) to detach before binding to a new one.
  3. Store LayoutManager creation in onViewCreated so each view gets its own instance.

Example fix

// before (shared field)
private final LinearLayoutManager lm = new LinearLayoutManager(ctx);
recyclerViewA.setLayoutManager(lm);
recyclerViewB.setLayoutManager(lm); // throws

// after
recyclerViewA.setLayoutManager(new LinearLayoutManager(ctx));
recyclerViewB.setLayoutManager(new LinearLayoutManager(ctx));
Defensive patterns

Strategy: validation

Validate before calling

if (lm != null && lm.getRecyclerView() != null) {
    // already attached elsewhere; create a fresh instance instead
    lm = new LinearLayoutManager(ctx);
}
recyclerView.setLayoutManager(lm);

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Creating one LinearLayoutManager instance and calling recyclerViewA.setLayoutManager(lm) then recyclerViewB.setLayoutManager(lm). Reusing a LayoutManager field across recreated fragments/activities without nulling it.

Common situations: Singleton or shared LayoutManager injected into multiple RecyclerViews. Fragment view recreation where the LM is retained in a ViewModel and re-applied to a new RecyclerView instance.

Related errors


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