sschmid/Entitas · error · CollectorException

Unbalanced count with groups

Error message

Unbalanced count with groups ({groups.Length}) and group events ({groupEvents.Length}).

What it means

The Collector constructor requires one event matcher per group: each group must be paired with the GroupEvent (Added/Removed/AddedOrRemoved) that describes when it triggers collection. A length mismatch means the collector cannot map events onto groups and Entitas refuses to build it.

Solutions

  1. Make groupEvents.Length equal groups.Length, one GroupEvent per group
  2. Use the params overload Collector(context.GetGroup(m), GroupEvent.Added) for a single group
  3. Use GroupEvent.AddedOrRemoved for all groups if you don't need per-group granularity

Example fix

// before
new Collector<PlayerEntity>(ctx.GetGroup(Matcher.AllOf(0)), ctx.GetGroup(Matcher.AllOf(1)), GroupEvent.Added);
// after
new Collector<PlayerEntity>(new[] { ctx.GetGroup(Matcher.AllOf(0)), ctx.GetGroup(Matcher.AllOf(1)) }, new[] { GroupEvent.Added, GroupEvent.Added });
Defensive patterns

Strategy: validation

Validate before calling

if (groups.Length != groupEvents.Length)
    throw new ArgumentException("groups and groupEvents counts must match");

Try / catch

try { new Collector<TEntity>(groups, groupEvents); }
catch (Exception e) { Debug.LogError($"Collector config invalid: {e.Message}"); }

Prevention

When it happens

Trigger: new Collector<TEntity>(context.GetGroup(matcherA), context.GetGroup(matcherB), GroupEvent.Added) — two groups but only one GroupEvent (or vice versa); also passing groups array of length N with groupEvents of length M != N.

Common situations: Adding a group to a collector and forgetting to append a matching GroupEvent, or refactoring from the params single-group overload to the array overload and passing events as a single value.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Entitas/Collector/Collector.cs:41

        readonly GroupChanged<TEntity> _onEntityDelegate;

        string _toStringCache;

        /// Creates a Collector and will collect changed entities
        /// based on the specified groupEvent.
        public Collector(IGroup<TEntity> group, GroupEvent groupEvent) : this(new[] { group }, new[] { groupEvent }) { }

        /// Creates a Collector and will collect changed entities
        /// based on the specified groupEvents.
        public Collector(IGroup<TEntity>[] groups, GroupEvent[] groupEvents)
        {
            _collectedEntities = new HashSet<TEntity>(EntityEqualityComparer<TEntity>.Comparer);
            _groups = groups;
            _groupEvents = groupEvents;

            if (groups.Length != groupEvents.Length)
            {
                throw new CollectorException(
                    $"Unbalanced count with groups ({groups.Length}) and group events ({groupEvents.Length}).",
                    "Group and GroupEvents count must be equal."
                );
            }

            _onEntityDelegate = (_, entity, _, _) =>
            {
                if (_collectedEntities.Add(entity))
                    entity.Retain(this);
            };

            Activate();
        }

        /// Activates the Collector and will start collecting
        /// changed entities. Collectors are activated by default.
        public void Activate()
        {

View on GitHub (pinned to 37547d1bd2)