sschmid/Entitas · error · ContextEntityIndexDoesAlreadyExistException

ContextEntityIndexDoesAlreadyExistException(this…

Error message

ContextEntityIndexDoesAlreadyExistException(this, entityIndex.Name)

What it means

A context allows only one IEntityIndex per name. AddEntityIndex checks the internal dictionary keyed by index name and throws when an index with that exact name was already registered, preventing silent overwriting of an active index.

Solutions

  1. Use GetEntityIndex(name) first and only add when it returns null
  2. Give each index a unique name
  3. Remove the old index before adding a replacement if re-registration is intended

Example fix

// before
context.AddEntityIndex(new PrimaryEntityIndex<Entity, string>("Entities", ...)); // second call throws
// after
if (context.GetEntityIndex("Entities") == null)
    context.AddEntityIndex(new PrimaryEntityIndex<Entity, string>("Entities", ...));
Defensive patterns

Strategy: validation

Validate before calling

if (context.GetEntityIndex(name) == null)
    context.AddEntityIndex(index);

Prevention

When it happens

Trigger: Calling context.AddEntityIndex(new PrimaryEntityIndex<...>("SameName", ...)) twice, or re-adding indexes during scene reload/Reset without removing the previous ones.

Common situations: Duplicate index names from copy-pasted setup code, hot-reload or scene re-init re-running index registration, and multiple systems each registering an index with a shared name.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of sschmid/Entitas@37547d1bd2 (2026-09-14). Data as JSON: /api/errors/9317dae0d618b85c. Report an issue: GitHub.

Appendix: source

Thrown at src/Entitas/Context/Context.cs:278

                for (var i = 0; i < matcher.Indexes.Length; i++)
                {
                    var index = matcher.Indexes[i];
                    _groupsForIndex[index] ??= new List<IGroup<TEntity>>();
                    _groupsForIndex[index].Add(group);
                }

                OnGroupCreated?.Invoke(this, group);
            }

            return group;
        }

        /// Adds the IEntityIndex for the specified name.
        /// There can only be one IEntityIndex per name.
        public void AddEntityIndex(IEntityIndex entityIndex)
        {
            if (_entityIndexes.ContainsKey(entityIndex.Name))
                throw new ContextEntityIndexDoesAlreadyExistException(this, entityIndex.Name);

            _entityIndexes.Add(entityIndex.Name, entityIndex);
        }

        /// Gets the IEntityIndex for the specified name.
        public IEntityIndex GetEntityIndex(string name)
        {
            if (!_entityIndexes.TryGetValue(name, out var entityIndex))
                throw new ContextEntityIndexDoesNotExistException(this, name);

            return entityIndex;
        }

        /// Resets the creationIndex back to 0.
        public void ResetCreationIndex() => _creationIndex = 0;

        /// Clears the componentPool at the specified index.
        public void ClearComponentPool(int index) => _componentPools[index]?.Clear();

View on GitHub (pinned to 37547d1bd2)