{"record":{"id":"0d561d6095bc083d","repo":"EllanJiang/GameFramework","slug":"type-is-invalid-referencepool-referencecollection","errorCode":null,"errorMessage":"Type is invalid.","messagePattern":"Type is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs","lineNumber":96,"sourceCode":"                get\n                {\n                    return m_AddReferenceCount;\n                }\n            }\n\n            public int RemoveReferenceCount\n            {\n                get\n                {\n                    return m_RemoveReferenceCount;\n                }\n            }\n\n            public T Acquire<T>() where T : class, IReference, new()\n            {\n                if (typeof(T) != m_ReferenceType)\n                {\n                    throw new GameFrameworkException(\"Type is invalid.\");\n                }\n\n                m_UsingReferenceCount++;\n                m_AcquireReferenceCount++;\n                lock (m_References)\n                {\n                    if (m_References.Count > 0)\n                    {\n                        return (T)m_References.Dequeue();\n                    }\n                }\n\n                m_AddReferenceCount++;\n                return new T();\n            }\n\n            public IReference Acquire()\n            {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs#L78-L114","documentation":"ReferencePool stores one ReferenceCollection per concrete IReference type. When Acquire<T>() is called, the nested ReferenceCollection checks that the generic type parameter T exactly matches the collection's stored reference type (m_ReferenceType) before handing out an instance. A mismatch means a reference of a different type was requested from the wrong collection, indicating a pooling bookkeeping bug.","triggerScenarios":"Acquire<T>() where typeof(T) differs from the type with which the collection was created — typically reached when ReferencePool.Release stored an object under one type but Acquire<T> resolves another (e.g. derived vs. base type, or two distinct types with similar names), or internal collection lookup returned the wrong bucket.","commonSituations":"Releasing a derived class instance then acquiring via the base class type (or vice versa); renaming/re-factoring a reference class so stale code acquires the old type; generic helper wrappers that pass a wrong T through to ReferencePool.Acquire.","solutions":["Ensure the T passed to ReferencePool.Acquire<T> is exactly the same concrete type that was used with Add<T> and Release — no base/derived mixing.","Check that every Release call releases the exact type it acquired; cast or inspect the object's runtime type if in doubt.","Reproduce with strict checking enabled and log typeof(T) versus the collection's m_ReferenceType at both Acquire and Release sites."],"exampleFix":"// before\nMyBaseReference r = ReferencePool.Acquire(typeof(MyDerivedReference)); // type mismatch\n\n// after\nMyDerivedReference r = ReferencePool.Acquire<MyDerivedReference>(); // exact type for both Add/Acquire/Release","handlingStrategy":"type-guard","validationCode":"// before acquire\nType requested = typeof(T); // must equal the exact type used in Add/Release\n","typeGuard":"static bool SamePoolType<T>() where T : class, IReference, new() => typeof(T) == typeof(T); // use one generic helper per concrete reference type so T is fixed at compile time","tryCatchPattern":"try { r = ReferencePool.Acquire<T>(); }\ncatch (GameFrameworkException ex) when (ex.Message == \"Type is invalid.\")\n{\n    // log typeof(T) and the Add/Release sites to find the base/derived mix-up\n}","preventionTips":["Centralize Acquire/Add/Release for each reference type in one static helper so T can never diverge.","Never mix base and derived types in the same pool lifecycle.","Search call sites for typeof()/GetType() uses that could route the wrong Type into the pool."],"tags":["object-pool","type-mismatch","generics","reference-pool"],"backgroundTag":"type-mismatch","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}