sschmid/Entitas · error · SingleEntityException

Expected exactly one entity in collection but found

Error message

Expected exactly one entity in collection but found {count}!

What it means

Thrown by the SingleEntity() extension when the collection does not contain exactly one entity. It is a strict assertion helper: use it only where the entity count is guaranteed to be 1, otherwise it fails with SingleEntityException reporting the actual count.

Solutions

  1. Check count first: if (collection.Count == 1) use SingleEntity, else handle 0/many
  2. Use context.GetGroup(matcher).GetSingleEntity() which returns null for empty instead of throwing, or check its result for null
  3. Enforce singleton creation in an initialization system so exactly one exists before consumers run
  4. Narrow the matcher (Matcher.AllOf) so only the intended singleton matches

Example fix

// before
var score = context.GetGroup(ScoreMatcher).GetEntities().SingleEntity(); // throws when 0 or >1
// after
var entities = context.GetGroup(ScoreMatcher).GetEntities();
Entity scoreEntity = entities.Length == 1 ? entities.SingleEntity() : null;
if (scoreEntity != null) {
    // use scoreEntity
}
Defensive patterns

Strategy: validation

Validate before calling

var es = group.GetEntities();
if (es.Length == 1) { var e = es.SingleEntity(); }

Type guard

bool HasSingleEntity(ICollection<Entity> c) => c.Count == 1;

Try / catch

try { var e = collection.SingleEntity(); }
catch (SingleEntityException ex) { Debug.LogWarning($"expected 1 entity: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling collection.SingleEntity() when the group/collection has 0 entities (nothing matched) or more than 1 (multiple entities matched the same criteria).

Common situations: Assuming a singleton exists before it was created (first frames of the game); systems creating duplicate config/scoreboard entities; groups matched too broadly so several entities fit; calling before initialization finished.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at src/Entitas/Extensions/CollectionExtension.cs:14

using System.Collections.Generic;
using System.Linq;

namespace Entitas
{
    public static class CollectionExtension
    {
        /// Returns the only entity in the collection.
        /// It will throw an exception if the collection doesn't have
        /// exactly one entity.
        public static Entity SingleEntity(this ICollection<Entity> collection)
        {
            if (collection.Count != 1)
                throw new SingleEntityException(collection.Count);

            return collection.First();
        }

        /// Returns the only entity in the collection.
        /// It will throw an exception if the collection doesn't have
        /// exactly one entity.
        public static TEntity SingleEntity<TEntity>(this ICollection<TEntity> collection) where TEntity : Entity
        {
            if (collection.Count != 1)
                throw new SingleEntityException(collection.Count);

            return collection.First();
        }
    }

    public class SingleEntityException : EntitasException
    {

View on GitHub (pinned to 37547d1bd2)