sschmid/Entitas · error · EntityIsNotEnabledException
Cannot remove component
Error message
Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}! What it means
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.
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
Example fix
// before
entity.RemoveHealth(); // throws if entity was destroyed
// after
if (entity.isEnabled && entity.hasHealth) {
entity.RemoveHealth();
} Defensive patterns
Strategy: validation
Validate before calling
if (entity.isEnabled && entity.HasComponent(index)) entity.RemoveComponent(index);
Type guard
bool CanRemove(Entity e, int index) => e.isEnabled && e.HasComponent(index);
Try / catch
try { entity.RemoveComponent(index); }
catch (EntityIsNotEnabledException) { /* entity already destroyed; nothing to do */ } Prevention
- 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
When it happens
Trigger: Calling entity.RemoveComponent(index) or a generated e.RemovePosition() on an entity that was already destroyed via Destroy() or reclaimed by the context.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot replace component
- Cannot destroy !
- Cannot add component
- Cannot get component
- EntityIsAlreadyRetainedByOwnerException(_entity, owner)
AI-assisted analysis of sschmid/Entitas@37547d1bd2 (2026-09-14).
Data as JSON: /api/errors/77280047d0a106f1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Entitas/Entity/Entity.cs:157
$"Cannot add component '{_contextInfo.ComponentNames[index]}' to {this}!",
"You should check if an entity already has the component before adding it or use entity.ReplaceComponent()."
);
_components[index] = component;
_componentsCache = null;
_componentIndexesCache = null;
_toStringCache = null;
OnComponentAdded?.Invoke(this, index, component);
}
/// Removes a component at the specified index.
/// You can only remove a component at an index if it exists.
/// The preferred way is to use the
/// generated methods from the code generator.
public void RemoveComponent(int index)
{
if (!_isEnabled)
throw new EntityIsNotEnabledException($"Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}!");
if (!HasComponent(index))
throw new EntityDoesNotHaveComponentException(index,
$"Cannot remove component '{_contextInfo.ComponentNames[index]}' from {this}!",
"You should check if an entity has the component before removing it.");
HandleComponent(index, null);
}
/// Replaces an existing component at the specified index
/// or adds it if it doesn't exist yet.
/// The preferred way is to use the
/// generated methods from the code generator.
public void ReplaceComponent(int index, IComponent component)
{
if (!_isEnabled)
throw new EntityIsNotEnabledException($"Cannot replace component '{_contextInfo.ComponentNames[index]}' on {this}!");
View on GitHub (pinned to 37547d1bd2)