{"record":{"id":"49e7096ce2260ca9","repo":"sschmid/Entitas","slug":"cannot-release-entity","errorCode":null,"errorMessage":"Cannot release {entity}!","messagePattern":"Cannot release (.+?)!","errorType":"exception","errorClass":"EntityIsNotDestroyedException","httpStatus":null,"severity":"error","filePath":"src/Entitas/Context/Context.cs","lineNumber":144,"sourceCode":"                        events[i]?.Invoke(groups[i], tEntity, index, component);\n\n                    events.Clear();\n                    groupChangedListPool.Push(events);\n                }\n            };\n\n            _onComponentReplacedDelegate = (entity, index, previousComponent, newComponent) =>\n            {\n                var groups = _groupsForIndex[index];\n                if (groups != null)\n                    for (var i = 0; i < groups.Count; i++)\n                        groups[i].UpdateEntity((TEntity)entity, index, previousComponent, newComponent);\n            };\n\n            _OnEntityReleasedDelegate = entity =>\n            {\n                if (entity.IsEnabled)\n                    throw new EntityIsNotDestroyedException($\"Cannot release {entity}!\");\n\n                var tEntity = (TEntity)entity;\n                entity.RemoveAllOnEntityReleasedHandlers();\n                _retainedEntities.Remove(tEntity);\n                _reusableEntities.Push(tEntity);\n            };\n\n            _OnDestroyEntityDelegate = entity =>\n            {\n                var tEntity = (TEntity)entity;\n                var removed = _entities.Remove(tEntity);\n                if (!removed)\n                    throw new ContextDoesNotContainEntityException(\n                        $\"'{this}' cannot destroy {tEntity}!\",\n                        \"This cannot happen!?!\"\n                    );\n\n                _entitiesCache = null;","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/sschmid/Entitas/blob/37547d1bd280f3f1c1ef7edb44f2a206660fbfb4/src/Entitas/Context/Context.cs#L126-L162","documentation":"Context's internal OnEntityReleased handler throws this when an entity is released (its retain count dropping) while it is still enabled, i.e. it was not destroyed first. In Entitas an entity must be destroyed (removed from the context) before its last retain is released so it can be recycled.","triggerScenarios":"An object that Retain()ed an entity calls Release() after the entity has been recycled by Destroy() but is again enabled, or releasing a retained entity that was never destroyed while enabled — the guard fires when entity.IsEnabled is true at release time.","commonSituations":"Custom Retain/Release usage (e.g. EntityLink-like systems), asymmetric retain/release in pools, or releasing a live entity obtained from context.CreateEntity().","solutions":["Always call entity.Destroy() before the last entity.Release(this)","Balance every Retain with exactly one Release on entity destruction","Audit custom retaining code (indexes, pools) for missed Release calls","Check entity.IsEnabled / entity.retainCount before releasing"],"exampleFix":"// before\nentity.Release(this); // throws when entity still enabled\n// after\nif (entity.IsEnabled) entity.Destroy();\nentity.Release(this);","handlingStrategy":"type-guard","validationCode":"if (entity.IsEnabled) entity.Destroy();\nentity.Release(this);","typeGuard":"bool CanRelease(IEntity e) => !e.IsEnabled;","tryCatchPattern":null,"preventionTips":["Balance every Retain with a Release","Destroy entities before final Release","Audit custom retainers (indexes, pools) for leaks"],"tags":["entitas","entity","retain-release","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"37547d1bd280f3f1c1ef7edb44f2a206660fbfb4","analyzedAt":"2026-09-14T00:26:23.246Z","contentChangedAt":"2026-09-14T00:26:23.246Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}