{"record":{"id":"77280047d0a106f1","repo":"sschmid/Entitas","slug":"cannot-remove-component-contextinfo-componentnames-index","errorCode":null,"errorMessage":"Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}!","messagePattern":"Cannot remove component '(.+?)' from (.+?)!","errorType":"exception","errorClass":"EntityIsNotEnabledException","httpStatus":null,"severity":"error","filePath":"src/Entitas/Entity/Entity.cs","lineNumber":157,"sourceCode":"                    $\"Cannot add component '{_contextInfo.ComponentNames[index]}' to {this}!\",\n                    \"You should check if an entity already has the component before adding it or use entity.ReplaceComponent().\"\n                );\n\n            _components[index] = component;\n            _componentsCache = null;\n            _componentIndexesCache = null;\n            _toStringCache = null;\n            OnComponentAdded?.Invoke(this, index, component);\n        }\n\n        /// Removes a component at the specified index.\n        /// You can only remove a component at an index if it exists.\n        /// The preferred way is to use the\n        /// generated methods from the code generator.\n        public void RemoveComponent(int index)\n        {\n            if (!_isEnabled)\n                throw new EntityIsNotEnabledException($\"Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}!\");\n\n            if (!HasComponent(index))\n                throw new EntityDoesNotHaveComponentException(index,\n                    $\"Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}!\",\n                    \"You should check if an entity has the component before removing it.\");\n\n            HandleComponent(index, null);\n        }\n\n        /// Replaces an existing component at the specified index\n        /// or adds it if it doesn't exist yet.\n        /// The preferred way is to use the\n        /// generated methods from the code generator.\n        public void ReplaceComponent(int index, IComponent component)\n        {\n            if (!_isEnabled)\n                throw new EntityIsNotEnabledException($\"Cannot replace component '{_contextInfo.ComponentNames[index]}' on {this}!\");\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/sschmid/Entitas/blob/37547d1bd280f3f1c1ef7edb44f2a206660fbfb4/src/Entitas/Entity/Entity.cs#L139-L175","documentation":"Thrown by Entity.RemoveComponent when the entity has been destroyed (_isEnabled == false). Even before checking whether the component exists, Entitas rejects any component operation on a disabled (destroyed) entity, because its component table is no longer meaningful.","triggerScenarios":"Calling entity.RemoveComponent(index) or a generated e.RemovePosition() on an entity that was already destroyed via Destroy() or reclaimed by the context.","commonSituations":"Cleanup systems running after teardown; listeners firing after entity destruction; a destroyed entity kept in a group snapshot and then mutated in a later frame.","solutions":["Guard with if (entity.isEnabled) before removing components","Unsubscribe from OnComponentRemoved/OnDestroyEntity when the entity is destroyed so stale callbacks never run","Retain the entity (SafeAERC) if it must outlive its context lifetime legitimately","Re-fetch entities from the context each update rather than holding destroyed references"],"exampleFix":"// before\nentity.RemoveHealth(); // throws if entity was destroyed\n// after\nif (entity.isEnabled && entity.hasHealth) {\n    entity.RemoveHealth();\n}","handlingStrategy":"validation","validationCode":"if (entity.isEnabled && entity.HasComponent(index)) entity.RemoveComponent(index);","typeGuard":"bool CanRemove(Entity e, int index) => e.isEnabled && e.HasComponent(index);","tryCatchPattern":"try { entity.RemoveComponent(index); }\ncatch (EntityIsNotEnabledException) { /* entity already destroyed; nothing to do */ }","preventionTips":["Combine isEnabled and HasComponent checks before removal","Purge destroyed entities from system-internal lists","Let OnDestroyEntity clean up subscriptions","Use generated has-properties (e.hasX) for readability"],"tags":["csharp","entitas","entity-lifecycle","destroyed-entity"],"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"}