sschmid/Entitas · error · ContextInfoException
ContextInfoException(this, contextInfo)
Error message
ContextInfoException(this, contextInfo)
What it means
When a custom ContextInfo (with component names) is passed to the Context constructor, its ComponentNames array length must exactly equal totalComponents. Entitas validates this because component names are indexed by component index; a mismatch would produce wrong or missing names.
Solutions
- Ensure ComponentNames.Length equals the totalComponents argument
- Regenerate or update ContextInfo after changing the component list
- Let contextInfo be null (auto-generates "Index N" names) if you don't need custom names
Example fix
// before
new Context<Entity>(3, 0, new ContextInfo("Game", new[] { "A", "B" }, types)); // 2 names vs 3 components
// after
new Context<Entity>(3, 0, new ContextInfo("Game", new[] { "A", "B", "C" }, types)); Defensive patterns
Strategy: validation
Validate before calling
if (contextInfo != null && contextInfo.ComponentNames.Length != totalComponents)
throw new ArgumentException("ComponentNames length must equal totalComponents"); Prevention
- Generate ContextInfo from the same source as component list
- Assert lengths in a test
- Avoid hand-maintained duplicate component name lists
When it happens
Trigger: new Context<MyEntity>(numComponents, 0, new ContextInfo("Game", new[] { "Position", "Velocity" }, componentTypes)) where ComponentNames.Length != totalComponents.
Common situations: Manually maintained ContextInfo not updated after adding/removing a component class, code-gen config changes, or reusing one ContextInfo across contexts with different totalComponents counts.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ' ' cannot destroy !
- ContextStillHasRetainedEntitiesException(this…
- EntityLink is already linked to
- EntityLink is already unlinked!
- Unbalanced count with groups
AI-assisted analysis of sschmid/Entitas@37547d1bd2 (2026-09-14).
Data as JSON: /api/errors/c17ed0791374476e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Entitas/Context/Context.cs:92
readonly EntityEvent _OnEntityReleasedDelegate;
readonly EntityEvent _OnDestroyEntityDelegate;
/// The preferred way to create a context is to use the generated methods
/// from the code generator, e.g. var context = new MainContext();
public Context(int totalComponents, Func<TEntity> entityFactory) : this(totalComponents, 0, null, null, entityFactory) { }
/// The preferred way to create a context is to use the generated methods
/// from the code generator, e.g. var context = new GameContext();
public Context(int totalComponents, int startCreationIndex, ContextInfo contextInfo, Func<Entity, IAERC> aercFactory, Func<TEntity> entityFactory)
{
_totalComponents = totalComponents;
_creationIndex = startCreationIndex;
if (contextInfo != null)
{
_contextInfo = contextInfo;
if (contextInfo.ComponentNames.Length != totalComponents)
throw new ContextInfoException(this, contextInfo);
}
else
{
var componentNames = new string[_totalComponents];
for (var i = 0; i < componentNames.Length; i++)
componentNames[i] = "Index " + i;
_contextInfo = new ContextInfo("Unnamed Context", componentNames, null);
}
_aercFactory = aercFactory ?? SafeAERC.Delegate;
_entityFactory = entityFactory;
_groupsForIndex = new List<IGroup<TEntity>>[totalComponents];
_componentPools = new Stack<IComponent>[totalComponents];
_entityIndexes = new Dictionary<string, IEntityIndex>();
var groupChangedListPool = new Stack<List<GroupChanged<TEntity>>>();View on GitHub (pinned to 37547d1bd2)