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

  1. Verify the object was obtained from this exact pool via Spawn and not from another pool or direct construction.
  2. Call Unspawn on the same IObjectPool<T> instance that spawned the object; check Name/typeof(T) in the message against your registration.
  3. Ensure the object was not already released (double-recycle) — track in-flight state and skip the second Unspawn.
  4. 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

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


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)