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
- Create a new LayoutManager instance per RecyclerView; do not share instances.
- If reusing programmatically, first call oldRecyclerView.setLayoutManager(null) to detach before binding to a new one.
- 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
- Create a new LayoutManager instance per RecyclerView.
- If migrating an LM to a new RecyclerView, call setLayoutManager(null) on the old one first.
- Do not store a LayoutManager in a shared singleton/ViewModel for reuse across views.
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
- Called attach on a child which is not detached: {vh}
- called detach on an already detached child {vh}
- view is not a child, cannot hide {}
- Layout positions must be non-negative
- Pixel distance must be non-negative
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/b41973eb49e3d7cd.
Report an issue: GitHub.