{"record":{"id":"b72fc57f06a48b92","repo":"PhilJay/MPAndroidChart","slug":"the-object-to-recycle-already-belongs-to-poolid-o","errorCode":null,"errorMessage":"The object to recycle already belongs to poolId {object.currentOwnerId}.  Object cannot belong to two different pool instances simultaneously!","messagePattern":"The object to recycle already belongs to poolId (.+?)\\.  Object cannot belong to two different pool instances simultaneously!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"MPChartLib/src/main/java/com/github/mikephil/charting/utils/ObjectPool.java","lineNumber":137,"sourceCode":"        T result = (T)objects[this.objectsPointer];\n        result.currentOwnerId = Poolable.NO_OWNER;\n        this.objectsPointer--;\n\n        return result;\n    }\n\n    /**\n     * Recycle an instance of Poolable that this pool is capable of generating.\n     * The T instance passed must not already exist inside this or any other ObjectPool instance.\n     *\n     * @param object An object of type T to recycle\n     */\n    public synchronized void recycle(T object){\n        if(object.currentOwnerId != Poolable.NO_OWNER){\n            if(object.currentOwnerId == this.poolId){\n                throw new IllegalArgumentException(\"The object passed is already stored in this pool!\");\n            }else {\n                throw new IllegalArgumentException(\"The object to recycle already belongs to poolId \" + object.currentOwnerId + \".  Object cannot belong to two different pool instances simultaneously!\");\n            }\n        }\n\n        this.objectsPointer++;\n        if(this.objectsPointer >= objects.length){\n            this.resizePool();\n        }\n\n        object.currentOwnerId = this.poolId;\n        objects[this.objectsPointer] = object;\n\n    }\n\n    /**\n     * Recycle a List of Poolables that this pool is capable of generating.\n     * The T instances passed must not already exist inside this or any other ObjectPool instance.\n     *\n     * @param objects A list of objects of type T to recycle","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/PhilJay/MPAndroidChart/blob/9c7275a0596a7ac0e50ca566e680f7f9d73607af/MPChartLib/src/main/java/com/github/mikephil/charting/utils/ObjectPool.java#L119-L155","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nPoolable o = poolA.get();\npoolB.recycle(o); // throws: belongs to poolA\n\n// after\nPoolable o = poolA.get();\npoolA.recycle(o); // return to the owner pool","handlingStrategy":"validation","validationCode":"if (object.currentOwnerId == Poolable.NO_OWNER || object.currentOwnerId == pool.getPoolId()) {\n    pool.recycle(object);\n} else {\n    Log.w(TAG, \"Object belongs to pool \" + object.currentOwnerId);\n}","typeGuard":"boolean belongsToPool(Poolable o, ObjectPool pool) {\n    return o.currentOwnerId == pool.getPoolId();\n}","tryCatchPattern":null,"preventionTips":["Recycle each object into the pool it came from.","Prefer a single pool per object type.","Track the owning pool id alongside acquired objects."],"tags":["object-pool","recycle","ownership","cross-pool"],"backgroundTag":null,"analyzedSha":"9c7275a0596a7ac0e50ca566e680f7f9d73607af","analyzedAt":"2026-08-14T00:17:56.136Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}