PhilJay/MPAndroidChart · error · IllegalArgumentException

The object passed is already stored in this pool!

Error message

The object passed is already stored in this pool!

What it means

Thrown by ObjectPool.recycle(T) when the object's currentOwnerId equals this pool's id, meaning it was already returned to this pool. Each Poolable tracks its owner; recycling the same instance twice into the same pool would duplicate it. This is the branch where object.currentOwnerId == this.poolId.

Source

Thrown at MPChartLib/src/main/java/com/github/mikephil/charting/utils/ObjectPool.java:135

        }

        T result = (T)objects[this.objectsPointer];
        result.currentOwnerId = Poolable.NO_OWNER;
        this.objectsPointer--;

        return result;
    }

    /**
     * Recycle an instance of Poolable that this pool is capable of generating.
     * The T instance passed must not already exist inside this or any other ObjectPool instance.
     *
     * @param object An object of type T to recycle
     */
    public synchronized void recycle(T object){
        if(object.currentOwnerId != Poolable.NO_OWNER){
            if(object.currentOwnerId == this.poolId){
                throw new IllegalArgumentException("The object passed is already stored in this pool!");
            }else {
                throw new IllegalArgumentException("The object to recycle already belongs to poolId " + object.currentOwnerId + ".  Object cannot belong to two different pool instances simultaneously!");
            }
        }

        this.objectsPointer++;
        if(this.objectsPointer >= objects.length){
            this.resizePool();
        }

        object.currentOwnerId = this.poolId;
        objects[this.objectsPointer] = object;

    }

    /**
     * Recycle a List of Poolables that this pool is capable of generating.
     * The T instances passed must not already exist inside this or any other ObjectPool instance.

View on GitHub (pinned to 9c7275a059)

Solutions

  1. Acquire a fresh object from the pool before recycling the same reference again.
  2. After recycle(obj), null out the local reference so it cannot be recycled twice.
  3. Use recycle(List) once over a batch rather than recycling individual duplicates.
  4. Add logging of object.currentOwnerId around recycle() to find double-return paths.

Example fix

// before
pool.recycle(obj);
// ...later, same ref still in scope
pool.recycle(obj); // throws: already in this pool

// after
pool.recycle(obj);
obj = null;
// next use:
obj = pool.get();
Defensive patterns

Strategy: validation

Validate before calling

if (object.currentOwnerId == Poolable.NO_OWNER) {
    pool.recycle(object);
} else {
    Log.w(TAG, "Object not eligible for recycle, owner=" + object.currentOwnerId);
}

Type guard

boolean isRecyclableHere(Poolable o, ObjectPool pool) {
    return o.currentOwnerId == Poolable.NO_OWNER;
}

Prevention

When it happens

Trigger: Calling pool.recycle(obj) twice for the same instance without re-acquiring it in between. Recycling an object still referenced by a list that was already bulk-recycled. Losing track of ownership in a manual object-lifecycle implementation.

Common situations: Custom view/chart recycling logic that returns objects on both a normal and an error path; recycling objects held in a cached collection that is also recycled; double-free bugs from copy-paste.

Related errors


AI-assisted analysis of PhilJay/MPAndroidChart@9c7275a059 (2026-08-14). Data as JSON: /api/errors/aee1badd807a36d5. Report an issue: GitHub.