{"record":{"id":"dda2c0c4d1c59224","repo":"EllanJiang/GameFramework","slug":"target-is-invalid","errorCode":null,"errorMessage":"Target is invalid.","messagePattern":"Target is invalid\\.","errorType":"validation","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs","lineNumber":302,"sourceCode":"            public void Unspawn(T obj)\n            {\n                if (obj == null)\n                {\n                    throw new GameFrameworkException(\"Object is invalid.\");\n                }\n\n                Unspawn(obj.Target);\n            }\n\n            /// <summary>\n            /// 回收对象。\n            /// </summary>\n            /// <param name=\"target\">要回收的对象。</param>\n            public void Unspawn(object target)\n            {\n                if (target == null)\n                {\n                    throw new GameFrameworkException(\"Target is invalid.\");\n                }\n\n                Object<T> internalObject = GetObject(target);\n                if (internalObject != null)\n                {\n                    internalObject.Unspawn();\n                    if (Count > m_Capacity && internalObject.SpawnCount <= 0)\n                    {\n                        Release();\n                    }\n                }\n                else\n                {\n                    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));\n                }\n            }\n\n            /// <summary>","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs#L284-L320","documentation":"ObjectPool<T>.Unspawn(object target) throws GameFrameworkException('Target is invalid.') when the raw target reference is null. The overload used for the actual recycle logic requires a non-null target that can be resolved back to a pooled Object<T> via GetObject.","triggerScenarios":"Calling Unspawn(obj.Target) where obj was null (this guards the internal delegation), or calling the object-target overload with a null reference directly.","commonSituations":"Chained recycle helpers that pass through a null; generic recycle utilities that don't check the target before delegating.","solutions":["Guard the target for null before calling the Unspawn(object) overload.","Ensure the preceding Unspawn(T) call received a non-null object so Target is valid.","Log the call site when target is null to find the upstream null source."],"exampleFix":"// before\npool.Unspawn(entity.Target);\n// after\nif (entity?.Target != null) pool.Unspawn(entity.Target);","handlingStrategy":"validation","validationCode":"if (target == null) { Log.Warning(\"Unspawn skipped: null target\"); return; }\npool.Unspawn(target);","typeGuard":"bool HasTarget(object target) => target != null;","tryCatchPattern":"try { pool.Unspawn(target); } catch (GameFrameworkException ex) when (ex.Message == \"Target is invalid.\") { Log.Warning(\"Unspawn target was null\"); }","preventionTips":["Validate targets in shared recycle helpers before delegating","Ensure ObjectReference.Target is initialized by Spawn before use","Avoid generic pass-through wrappers that skip null checks"],"tags":["null-argument","object-pool","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}