airbnb/epoxy · error · IllegalStateException

A pool was already found

Error message

A pool was already found

What it means

ActivityRecyclerPool caches one RecyclerView.RecycledViewPool per Activity context. When retrieving a pool for a context, if a second pool reference for the same context is encountered during iteration, its internal invariant is broken and this IllegalStateException is thrown.

Solutions

  1. Ensure the pool is registered at most once per Activity context (guard your registration code)
  2. Update epoxy-adapter — this indicates corrupted internal state in the pool registry
  3. As a workaround, construct the pool yourself and pass it to EpoxyRecyclerView instead of relying on ActivityRecyclerPool
Defensive patterns

Strategy: try-catch

Try / catch

try { pool = ActivityRecyclerPool.getPool(activity) } catch (e: IllegalStateException) { pool = RecyclerView.RecycledViewPool() }

Prevention

When it happens

Trigger: getPool(context) finding two pool references whose context === the requested context during iteration — i.e., a pool was registered twice for the same Activity.

Common situations: Re-registering or leaking pool registrations for the same Activity; unusual Activity recreation patterns causing duplicate entries in the internal map.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13). Data as JSON: /api/errors/4622aa28a37ee3a3. Report an issue: GitHub.

Appendix: source

Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/ActivityRecyclerPool.kt:38

     * only needs to hold pools for active activities.
     */
    private val pools = ArrayList<PoolReference>(5)

    @JvmOverloads
    fun getPool(
        context: Context,
        poolFactory: () -> RecyclerView.RecycledViewPool
    ): PoolReference {

        val iterator = pools.iterator()
        var poolToUse: PoolReference? = null

        while (iterator.hasNext()) {
            val poolReference = iterator.next()
            when {
                poolReference.context === context -> {
                    if (poolToUse != null) {
                        throw IllegalStateException("A pool was already found")
                    }
                    poolToUse = poolReference
                    // finish iterating to remove any old contexts
                }
                poolReference.context.isActivityDestroyed() -> {
                    // A pool from a different activity that was destroyed.
                    // Clear the pool references to allow the activity to be GC'd
                    poolReference.viewPool.clear()
                    iterator.remove()
                }
            }
        }

        if (poolToUse == null) {
            poolToUse = PoolReference(context, poolFactory(), this)
            context.lifecycle()?.addObserver(poolToUse)
            pools.add(poolToUse)
        }

View on GitHub (pinned to e45bd3a61f)