PhilJay/MPAndroidChart · error · IllegalArgumentException
The object to recycle already belongs to poolId {object.curr
Error message
The object to recycle already belongs to poolId {object.currentOwnerId}. Object cannot belong to two different pool instances simultaneously! What it means
Thrown by ObjectPool.recycle(T) when the object belongs to a different pool (currentOwnerId != NO_OWNER and != this.poolId). A Poolable can only be owned by one pool at a time; recycling it into another pool would violate that invariant. The offending poolId is interpolated into the message.
Source
Thrown at MPChartLib/src/main/java/com/github/mikephil/charting/utils/ObjectPool.java:137
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.
*
* @param objects A list of objects of type T to recycleView on GitHub (pinned to 9c7275a059)
Solutions
- Recycle each object into the exact pool that produced it (track owner via pool.getPoolId()).
- Maintain a single pool per object type instead of multiple pools.
- Before cross-pool handoff, ensure the object is NO_OWNER (it already is once acquired); do not recycle into a foreign pool.
- Tag acquired objects with their source pool id and assert on recycle.
Example fix
// before Poolable o = poolA.get(); poolB.recycle(o); // throws: belongs to poolA // after Poolable o = poolA.get(); poolA.recycle(o); // return to the owner pool
Defensive patterns
Strategy: validation
Validate before calling
if (object.currentOwnerId == Poolable.NO_OWNER || object.currentOwnerId == pool.getPoolId()) {
pool.recycle(object);
} else {
Log.w(TAG, "Object belongs to pool " + object.currentOwnerId);
} Type guard
boolean belongsToPool(Poolable o, ObjectPool pool) {
return o.currentOwnerId == pool.getPoolId();
} Prevention
- Recycle each object into the pool it came from.
- Prefer a single pool per object type.
- Track the owning pool id alongside acquired objects.
When it happens
Trigger: Acquiring an object from poolA and recycling it into poolB. Sharing Poolable subtypes across two pool instances. Reassigning an object to a newly created pool without releasing it from the old one.
Common situations: Multiple pools for the same type (e.g. one per chart); refactoring that introduced a second pool but reused old objects; cross-thread object handoff where each thread has its own pool.
Related errors
- The object passed is already stored in this pool!
- Object Pool must be instantiated with a capacity greater tha
AI-assisted analysis of PhilJay/MPAndroidChart@9c7275a059 (2026-08-14).
Data as JSON: /api/errors/b72fc57f06a48b92.
Report an issue: GitHub.