{"record":{"id":"3ebdb6119a1404dd","repo":"airbnb/epoxy","slug":"unboundedviewpool-does-not-support-setting-a-maximum-number","errorCode":null,"errorMessage":"UnboundedViewPool does not support setting a maximum number of recycled views","messagePattern":"UnboundedViewPool does not support setting a maximum number of recycled views","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/UnboundedViewPool.kt","lineNumber":24,"sourceCode":"import java.util.LinkedList\nimport java.util.Queue\n\n/**\n * Like its parent, UnboundedViewPool lets you share Views between multiple RecyclerViews. However\n * there is no maximum number of recycled views that it will store. This usually ends up being\n * optimal, barring any hard memory constraints, as RecyclerViews do not recycle more Views than\n * they need.\n */\ninternal class UnboundedViewPool : RecycledViewPool() {\n\n    private val scrapHeaps = SparseArray<Queue<ViewHolder>>()\n\n    override fun clear() {\n        scrapHeaps.clear()\n    }\n\n    override fun setMaxRecycledViews(viewType: Int, max: Int) {\n        throw UnsupportedOperationException(\n            \"UnboundedViewPool does not support setting a maximum number of recycled views\"\n        )\n    }\n\n    override fun getRecycledView(viewType: Int): ViewHolder? {\n        val scrapHeap = scrapHeaps.get(viewType)\n        return scrapHeap?.poll()\n    }\n\n    override fun putRecycledView(viewHolder: ViewHolder) {\n        getScrapHeapForType(viewHolder.itemViewType).add(viewHolder)\n    }\n\n    override fun getRecycledViewCount(viewType: Int): Int {\n        return scrapHeaps.get(viewType)?.size ?: 0\n    }\n\n    private fun getScrapHeapForType(viewType: Int): Queue<ViewHolder> {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/UnboundedViewPool.kt#L6-L42","documentation":"UnboundedViewPool is a RecyclerView.ViewHolder pool with no per-viewType size cap, implemented by overriding Epoxy's ViewPool. setMaxRecycledViews is intentionally unsupported because a cap contradicts the pool's unbounded design, so calling it always throws UnsupportedOperationException.","triggerScenarios":"Calling setMaxRecycledViews(viewType, max) on an UnboundedViewPool instance, directly or via code that configures a generic ViewPool/RecycledViewPool without knowing the concrete type.","commonSituations":"Shared pool-configuration utility code that sets max sizes for every pool including unbounded ones; swapping a bounded RecycledViewPool for UnboundedViewPool to fix memory churn while keeping the old sizing calls; copy-pasted RecyclerView setup.","solutions":["Remove the setMaxRecycledViews call when using UnboundedViewPool — it is unbounded by design.","Use a bounded pool (e.g. standard RecyclerView.RecycledViewPool or Epoxy's default ViewPool) if you need per-type caps.","Branch on pool type before configuring: only call setMaxRecycledViews when the pool supports it.","Control memory instead by limiting how many holders RecyclerView can create (layout manager hints) or using a different pool."],"exampleFix":"// before\nval pool = UnboundedViewPool()\npool.setMaxRecycledViews(0, 5) // throws\n\n// after\nval pool: RecyclerView.RecycledViewPool =\n  if (needCaps) RecyclerView.RecycledViewPool().apply { setMaxRecycledViews(0, 5) }\n  else UnboundedViewPool()","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fun RecyclerView.RecycledViewPool.setMaxIfSupported(viewType: Int, max: Int) {\n  if (this is UnboundedViewPool) return\n  setMaxRecycledViews(viewType, max)\n}","tryCatchPattern":null,"preventionTips":["Treat UnboundedViewPool as configure-free: never call sizing APIs on it.","Centralize pool creation so bounded/unbounded choice and configuration live in one place.","If you need caps, use the standard pool — don't fight the unbounded design."],"tags":["android","epoxy","recyclerview","view-pool","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"e45bd3a61fe3a1f130e184f5b8dcf172ab99025a","analyzedAt":"2026-09-13T03:24:16.052Z","contentChangedAt":"2026-09-13T03:24:16.052Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}