stride3d/stride · error · InvalidOperationException

Two elements of the collection have the same id

Error message

Two elements of the collection have the same id

What it means

Thrown by CollectionItemIdentifiers.Validate when two collection keys map to the same ItemId in keyToIdMap. Item ids must be unique per element, otherwise id-based tracking (undo/redo, serialization, diffing) becomes ambiguous, so the invariant is enforced eagerly.

Solutions

  1. Regenerate a fresh ItemId for each element instead of copying ids.
  2. Deduplicate: scan keyToIdMap and assign a new id to any duplicate before Validate.
  3. Rebuild the CollectionItemIdentifiers from the live collection so keys/ids are recomputed.
  4. Fix corrupted asset/serialization data containing duplicated ItemId guids.

Example fix

// before
foreach (var k in identifiers.Keys)
    identifiers[k] = fixedId; // duplicate ids
// after
foreach (var k in identifiers.Keys)
    identifiers[k] = ItemId.New(); // unique per element
Defensive patterns

Strategy: validation

Validate before calling

var idSet = new HashSet<ItemId>();
foreach (var key in identifiers.Keys)
{
    if (!idSet.Add(identifiers[key]))
        identifiers[key] = ItemId.New(); // regenerate duplicates
}
identifiers.Validate(isList);

Try / catch

try { identifiers.Validate(isList); }
catch (InvalidOperationException ex) when (ex.Message.Contains("same id"))
{
    // rebuild or deduplicate ids, then re-validate
}

Prevention

When it happens

Trigger: Calling Validate(isList) on a CollectionItemIdentifiers whose keyToIdMap contains duplicate ItemId values — typically after manual id assignment, deserialization of corrupted data, or code that reuses an id for two elements.

Common situations: Generating ids with a bad/constant source (e.g. a zeroed guid); cloning collections and copying ids instead of regenerating; hand-editing serialized asset YAML where ids were duplicated.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/a51b448ca0ee8cc2. Report an issue: GitHub.

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/Reflection/CollectionItemIdentifiers.cs:123

        }
        return id;
    }

    public void MarkAsDeleted(ItemId id)
    {
        deletedItems.Add(id);
    }

    public void UnmarkAsDeleted(ItemId id)
    {
        deletedItems.Remove(id);
    }

    public void Validate(bool isList)
    {
        var ids = new HashSet<ItemId>(keyToIdMap.Values);
        if (ids.Count != keyToIdMap.Count)
            throw new InvalidOperationException("Two elements of the collection have the same id");

        foreach (var deleted in deletedItems)
            ids.Add(deleted);

        if (ids.Count != keyToIdMap.Count + deletedItems.Count)
            throw new InvalidOperationException("An id is both marked as deleted and associated to a key of the collection.");
    }

    public object? GetKey(ItemId itemId)
    {
        object? output = null;
        // TODO: add indexing by guid to avoid O(n)
        foreach (var kvp in keyToIdMap)
        {
            if (kvp.Value == itemId)
            {
                if(output != null)
                    throw new InvalidOperationException("Two elements of the collection have the same id");

View on GitHub (pinned to 96fad776d2)