{"record":{"id":"2bf3706b9cf984e2","repo":"DrKLO/Telegram","slug":"the-view-does-not-have-a-viewholder-you-cannot-pa","errorCode":null,"errorMessage":"The view does not have a ViewHolder. You cannot pass arbitrary views to this method, they should be created by the Adapter","messagePattern":"The view does not have a ViewHolder\\. You cannot pass arbitrary views to this method, they should be created by the Adapter","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java","lineNumber":6058,"sourceCode":"        /**\n         * Binds the given View to the position. The View can be a View previously retrieved via\n         * {@link #getViewForPosition(int)} or created by\n         * {@link Adapter#onCreateViewHolder(ViewGroup, int)}.\n         * <p>\n         * Generally, a LayoutManager should acquire its views via {@link #getViewForPosition(int)}\n         * and let the RecyclerView handle caching. This is a helper method for LayoutManager who\n         * wants to handle its own recycling logic.\n         * <p>\n         * Note that, {@link #getViewForPosition(int)} already binds the View to the position so\n         * you don't need to call this method unless you want to bind this View to another position.\n         *\n         * @param view The view to update.\n         * @param position The position of the item to bind to this View.\n         */\n        public void bindViewToPosition(@NonNull View view, int position) {\n            ViewHolder holder = getChildViewHolderInt(view);\n            if (holder == null) {\n                throw new IllegalArgumentException(\"The view does not have a ViewHolder. You cannot\"\n                        + \" pass arbitrary views to this method, they should be created by the \"\n                        + \"Adapter\" + exceptionLabel());\n            }\n            final int offsetPosition = mAdapterHelper.findPositionOffset(position);\n            if (offsetPosition < 0 || offsetPosition >= mAdapter.getItemCount()) {\n                throw new IndexOutOfBoundsException(\"Inconsistency detected. Invalid item \"\n                        + \"position \" + position + \"(offset:\" + offsetPosition + \").\"\n                        + \"state:\" + mState.getItemCount() + exceptionLabel());\n            }\n            tryBindViewHolderByDeadline(holder, offsetPosition, position, FOREVER_NS);\n\n            final ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();\n            final LayoutParams rvLayoutParams;\n            if (lp == null) {\n                rvLayoutParams = (LayoutParams) generateDefaultLayoutParams();\n                holder.itemView.setLayoutParams(rvLayoutParams);\n            } else if (!checkLayoutParams(lp)) {\n                rvLayoutParams = (LayoutParams) generateLayoutParams(lp);","sourceCodeStart":6040,"sourceCodeEnd":6076,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java#L6040-L6076","documentation":"Recycler.bindViewToPosition throws IllegalArgumentException when the supplied view has no associated ViewHolder. bindViewToPosition is a LayoutManager-facing API that re-binds an existing adapter-created view to a new position; it looks up the view's ViewHolder via getChildViewHolderInt, and a null result means the view was never created by the Adapter (it is an arbitrary, non-RecyclerView view). Only views that passed through the adapter's onCreateViewHolder/onBindViewHolder lifecycle carry a ViewHolder (stored in LayoutParams.mViewHolder).","triggerScenarios":"A custom LayoutManager passing an externally created View (not from Recycler.getViewForPosition) into bindViewToPosition; manually inflating a view and handing it to the Recycler; a view whose ViewHolder was stripped during recycling due to a bug.","commonSituations":"Custom LayoutManager misuse; experimenting with Recycler internals; a third-party library that injects views into the Recycler bypassing the adapter; recycled view whose LayoutParams were replaced.","solutions":["Only pass views obtained from Recycler.getViewForPosition(int) (or getRecycledViewPool) into bindViewToPosition — these carry a ViewHolder.","In a custom LayoutManager, always obtain child views via the provided Recycler parameter, never via LayoutInflater or new View.","If you must introduce a non-adapter view, do so outside the Recycler pipeline (e.g. as a separate decorated header managed by the LayoutManager, not bound through the adapter)."],"exampleFix":"// before (custom LayoutManager)\nView v = LayoutInflater.from(ctx).inflate(R.layout.item, rv, false);\nrecycler.bindViewToPosition(v, pos); // v has no ViewHolder -> throw\n// after\nView v = recycler.getViewForPosition(pos); // created/bound by adapter, has VH\naddView(v);\nmeasureChildWithMargins(v, 0, 0);","handlingStrategy":"type-guard","validationCode":"// Only bind views obtained from the Recycler\nView v = recycler.getViewForPosition(pos); // guaranteed to have a ViewHolder\nrecycler.bindViewToPosition(v, pos);","typeGuard":"static boolean isAdapterCreatedView(View v, RecyclerView rv) {\n  ViewGroup.LayoutParams lp = v.getLayoutParams();\n  return lp instanceof RecyclerView.LayoutParams\n      && ((RecyclerView.LayoutParams) lp).getViewHolder() != null;\n}","tryCatchPattern":null,"preventionTips":["In a custom LayoutManager, obtain child views only via recycler.getViewForPosition.","Never inflate or construct views to pass into the Recycler bind API.","Treat the Recycler API as internal: prefer adapter-driven view creation."],"tags":["recyclerview","layoutmanager","recycler","viewholder","internal-api"],"backgroundTag":null,"analyzedSha":"45ab8f4308496e1f01026a97fcdb0d58a5274474","analyzedAt":"2026-08-14T05:19:30.815Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}