stride3d/stride · error · InvalidOperationException
An id is both marked as deleted and associated to a key of…
Error message
An id is both marked as deleted and associated to a key of the collection.
What it means
Thrown by CollectionItemIdentifiers.Validate when an ItemId appears both in deletedItems and as a live key's id in keyToIdMap. An id cannot simultaneously represent a deleted element and an active one; this state would corrupt id-based change tracking.
Solutions
- When re-adding an item whose id is in deletedItems, remove it from deletedItems or assign a brand-new ItemId.
- Before Validate, reconcile: for each key id present in deletedItems, either purge the deletion record or regenerate the id.
- Rebuild the CollectionItemIdentifiers from the current collection state to clear stale deletion markers.
- Fix undo/redo logic so delete-then-re-add sequences correctly restore the id.
Example fix
// before identifiers.MarkDeleted(itemId); identifiers["key"] = itemId; // id is both deleted and live // after identifiers.MarkDeleted(itemId); identifiers.RemoveDeleted(itemId); // or assign ItemId.New() identifiers["key"] = itemId;
Defensive patterns
Strategy: validation
Validate before calling
foreach (var key in identifiers.Keys.ToList())
{
var id = identifiers[key];
if (deletedIds.Contains(id))
identifiers[key] = ItemId.New(); // revive with a fresh id
}
identifiers.Validate(isList); Try / catch
try { identifiers.Validate(isList); }
catch (InvalidOperationException ex) when (ex.Message.Contains("deleted and associated"))
{
// rebuild identifiers from live collection or clear stale deletions
} Prevention
- Remove or clear deletion markers when re-adding an item with the same id.
- Assign a new ItemId when resurrecting previously deleted items.
- Fix undo/redo ordering so deletes and re-adds are replayed consistently.
- Call Validate after batch mutations to catch inconsistencies early.
When it happens
Trigger: Calling Validate after marking an id deleted while the same id is still assigned to a key — e.g. deleting an element but not removing its entry, or re-adding an element with a previously deleted id.
Common situations: Custom collection mutation code that removes values but reuses the deleted id; undo/redo implementations replaying add/delete in the wrong order; merging changes where a deleted item was re-added with its old id.
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
- Two elements of the collection have the same id
- Internal error, the collection has already muted to a…
- No Collection item identifier associated to the given…
- An item has been added to a collection that does not have a…
- IsObjectReference returned true for an object that is not…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2c176f1077cf8508.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/Reflection/CollectionItemIdentifiers.cs:129
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");
output = kvp.Key;
}
}
return output;
}
View on GitHub (pinned to 96fad776d2)