{"record":{"id":"b379b7b5b0b7620e","repo":"EllanJiang/GameFramework","slug":"entity-group-is-invalid","errorCode":null,"errorMessage":"Entity group is invalid.","messagePattern":"Entity group is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Entity/EntityManager.cs","lineNumber":171,"sourceCode":"                m_HideEntityCompleteEventHandler -= value;\n            }\n        }\n\n        /// <summary>\n        /// 实体管理器轮询。\n        /// </summary>\n        /// <param name=\"elapseSeconds\">逻辑流逝时间，以秒为单位。</param>\n        /// <param name=\"realElapseSeconds\">真实流逝时间，以秒为单位。</param>\n        internal override void Update(float elapseSeconds, float realElapseSeconds)\n        {\n            while (m_RecycleQueue.Count > 0)\n            {\n                EntityInfo entityInfo = m_RecycleQueue.Dequeue();\n                IEntity entity = entityInfo.Entity;\n                EntityGroup entityGroup = (EntityGroup)entity.EntityGroup;\n                if (entityGroup == null)\n                {\n                    throw new GameFrameworkException(\"Entity group is invalid.\");\n                }\n\n                entityInfo.Status = EntityStatus.WillRecycle;\n                entity.OnRecycle();\n                entityInfo.Status = EntityStatus.Recycled;\n                entityGroup.UnspawnEntity(entity);\n                ReferencePool.Release(entityInfo);\n            }\n\n            foreach (KeyValuePair<string, EntityGroup> entityGroup in m_EntityGroups)\n            {\n                entityGroup.Value.Update(elapseSeconds, realElapseSeconds);\n            }\n        }\n\n        /// <summary>\n        /// 关闭并清理实体管理器。\n        /// </summary>","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Entity/EntityManager.cs#L153-L189","documentation":"GameFramework throws this when recycling a queued entity whose owning entity group cannot be resolved. During Update, the EntityManager dequeues an entity from m_RecycleQueue, casts entity.EntityGroup to a concrete EntityGroup, and if the reference is null the entity cannot be unspawned back into any group, so the manager aborts with this GameFrameworkException. It indicates an internal invariant violation: an entity entered the recycle queue without a valid, registered group.","triggerScenarios":"Calling EntityManager.RecycleEntity (directly or via Entity.Recycle) for an entity whose EntityGroup reference is null, or whose group was set to a type that is not the concrete EntityGroup class (failed cast). Also occurs if the entity was obtained outside a registered group or the group was somehow cleared before the deferred recycle processed in Update.","commonSituations":"Manual entity lifecycle manipulation (spawning/recycling entities bypassing the group API), destroying or clearing an entity group while entities from it are still pending recycle in the queue, custom IEntity implementations that never set EntityGroup, and calling RecycleEntity after shutdown/clear of the entity component.","solutions":["Ensure entities are only created via EntityGroup.SpawnEntity and only recycled while their group still exists in the EntityManager.","Do not destroy or remove entity groups while entities from that group are still in the recycle queue; call RecycleEntity before group removal.","Verify custom IEntity implementations correctly set EntityGroup and return the concrete GameFramework EntityGroup instance from the EntityGroup property.","Check game shutdown order so the Entity component is not cleared before pending recycles are processed."],"exampleFix":"// before\ngameFrameworkEntityGroup.Destroy();\nentity.Recycle(); // group already destroyed -> EntityGroup null\n\n// after\nif (entityGroup.HasEntity(entity))\n{\n    entity.Recycle(); // recycle while group still valid\n}\ngameFrameworkEntityGroup.Destroy();","handlingStrategy":"validation","validationCode":"if (entity == null || entity.EntityGroup == null)\n{\n    // skip recycle or log instead of calling RecycleEntity\n    return;\n}","typeGuard":"bool CanRecycle(IEntity entity) => entity?.EntityGroup != null;","tryCatchPattern":"try\n{\n    entityManager.RecycleEntity(entity);\n}\ncatch (GameFrameworkException ex)\n{\n    Debug.LogWarning($\"Recycle failed: {ex.Message}; destroying entity instead\");\n}","preventionTips":["Only recycle entities obtained from EntityGroup.SpawnEntity.","Never remove/destroy an entity group while its entities may be pending recycle.","Keep custom IEntity implementations assigning EntityGroup correctly.","Recycle all entities before framework shutdown/clear."],"tags":["gameframework","entity","null-reference","internal-state"],"backgroundTag":"internal-invariant-violation","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"}