EllanJiang/GameFramework · error · GameFrameworkException
Can not find target in object pool
Error message
Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'. What it means
Thrown by ObjectPool<T>.Unspawn(object target) when GetObject(target) cannot find the target in this pool. The message includes the pool name (TypeNamePair of typeof(T) and Name), the target's type, and its value to help identify the mismatch. It means you tried to recycle an object into a pool that never spawned it (or a different pool owns it).
Solutions
- Verify the object was obtained from this exact pool via Spawn and not from another pool or direct construction.
- Call Unspawn on the same IObjectPool<T> instance that spawned the object; check Name/typeof(T) in the message against your registration.
- Ensure the object was not already released (double-recycle) — track in-flight state and skip the second Unspawn.
- If using a base-typed target, ensure the pool stores the same runtime instance (no copies/struct boxing).
Example fix
// before entityPool.Unspawn(bullet); // bullet actually came from bulletPool // after bulletPool.Unspawn(bullet);
Defensive patterns
Strategy: try-catch
Validate before calling
if (target != null && ownerPool != null && ReferenceEquals(ownerPool, pool)) pool.Unspawn(target);
Type guard
bool BelongsToPool<T>(IObjectPool<T> pool, T obj) where T : ObjectBase => obj != null && pool.CanSpawn(obj.Name); // verify ownership path in your pooling layer
Try / catch
try { pool.Unspawn(target); } catch (GameFrameworkException ex) when (ex.Message.Contains("Can not find target in object pool")) { Log.Error($"Target {target} not owned by pool {pool.Name}; check spawn origin"); } Prevention
- Always unspawn into the same pool instance that spawned the object
- Never Unspawn objects created with 'new' instead of Spawn
- Set references to null after Unspawn to catch double-recycle bugs
- Keep a spawn->pool ownership map if objects move between systems
When it happens
Trigger: Recycling an object into the wrong pool instance; calling Unspawn on an object created with 'new' instead of obtained via Spawn; recycling after the pool released the object (Release/ReleaseAllUnused) so the mapping no longer exists; using the same target in multiple pools.
Common situations: Mistyped pool names causing lookup against pool A while the object came from pool B; object still referenced after a pool Clear; duplicate reference classes where the boxed target differs from the stored one.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Type is invalid.
- The reference has been released.
- Reference is invalid.
- Reference type is invalid.
- Reference type is not a non-abstract class type.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/2478914da6b0d34d.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs:316
public void Unspawn(object target)
{
if (target == null)
{
throw new GameFrameworkException("Target is invalid.");
}
Object<T> internalObject = GetObject(target);
if (internalObject != null)
{
internalObject.Unspawn();
if (Count > m_Capacity && internalObject.SpawnCount <= 0)
{
Release();
}
}
else
{
throw new GameFrameworkException(Utility.Text.Format("Can not find target in object pool '{0}', target type is '{1}', target value is '{2}'.", new TypeNamePair(typeof(T), Name), target.GetType().FullName, target));
}
}
/// <summary>
/// 设置对象是否被加锁。
/// </summary>
/// <param name="obj">要设置被加锁的对象。</param>
/// <param name="locked">是否被加锁。</param>
public void SetLocked(T obj, bool locked)
{
if (obj == null)
{
throw new GameFrameworkException("Object is invalid.");
}
SetLocked(obj.Target, locked);
}
View on GitHub (pinned to d0c010b051)