sschmid/Entitas · error · ContextStillHasRetainedEntitiesException
ContextStillHasRetainedEntitiesException(this…
Error message
ContextStillHasRetainedEntitiesException(this, _retainedEntities)
What it means
DestroyAllEntities destroys all entities and clears the set, then asserts no entities remain retained (some object still holds a Retain). If retained entities exist, recycling bookkeeping would be corrupted, so Entitas throws instead of leaking them silently.
Solutions
- Ensure all retainers Release entities (e.g. Unlink all EntityLinks) before DestroyAllEntities
- Clear/reset all entity indexes and pools before resetting the context
- Fix asymmetry where Retain is called without a matching Release
Example fix
// before
context.Reset(); // throws if EntityLinks still retain entities
// after
foreach (var link in Object.FindObjectsOfType<EntityLink>())
link.Unlink();
context.Reset(); Defensive patterns
Strategy: validation
Validate before calling
foreach (var link in Object.FindObjectsOfType<EntityLink>())
if (link.entity != null) link.Unlink();
context.DestroyAllEntities(); Try / catch
try { context.Reset(); }
catch (Exception e) { Debug.LogError("Retained entities remain: release all retainers before reset"); } Prevention
- Unlink all EntityLinks before teardown
- Reset entity indexes before destroying entities
- Symmetric Retain/Release in all systems
When it happens
Trigger: Calling context.Reset() or context.DestroyAllEntities() while external systems (indexes, pools, EntityLink, custom retainers) still hold Retain on entities that were destroyed.
Common situations: Forgetting to Unlink EntityLink components before context teardown, custom entity indexes retaining entities, or editor/test teardown not releasing retained entities.
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
- ContextInfoException(this, contextInfo)
- Cannot release !
- ' ' cannot destroy !
- EntityLink is already linked to
- EntityLink is already unlinked!
AI-assisted analysis of sschmid/Entitas@37547d1bd2 (2026-09-14).
Data as JSON: /api/errors/9a2c0ef1527eefae.
Report an issue: GitHub.
Appendix: source
Thrown at src/Entitas/Context/Context.cs:228
entity.OnDestroyEntity += _OnDestroyEntityDelegate;
OnEntityCreated?.Invoke(this, entity);
return entity;
}
/// Destroys all entities in the context.
/// Throws an exception if there are still retained entities.
public void DestroyAllEntities()
{
var entities = GetEntities();
for (var i = 0; i < entities.Length; i++)
entities[i].Destroy();
_entities.Clear();
if (_retainedEntities.Count != 0)
throw new ContextStillHasRetainedEntitiesException(this, _retainedEntities);
}
/// Determines whether the context has the specified entity.
public bool HasEntity(TEntity entity) => _entities.Contains(entity);
/// Returns all entities which are currently in the context.
public TEntity[] GetEntities()
{
return _entitiesCache ??= _entities.ToArray();
}
/// Returns all entities matching the specified matcher.
public TEntity[] GetEntities(IMatcher<TEntity> matcher)
{
return GetGroup(matcher).GetEntities();
}
/// Returns a group for the specified matcher.View on GitHub (pinned to 37547d1bd2)