stride3d/stride · error · InvalidOperationException
No Collection item identifier associated to the given…
Error message
No Collection item identifier associated to the given collection.
What it means
AssetObjectNodeExtended tracks collection item identities (CollectionItemIdentifiers) attached to a Quantum node. IsItemDeleted needs the id registry for the node's retrieved collection to check whether a given ItemId is deleted; if the retrieved instance has no associated CollectionItemIdentifiers, the invariant is broken and it throws InvalidOperationException.
Solutions
- Ensure the collection actually has collection item identifiers (no NonIdentifiableCollectionItemsAttribute) and that asset metadata was loaded/upgraded so ids exist before querying IsItemDeleted.
- Use TryGetCollectionItemIds / TryIdToIndex-style checks (or CollectionItemIdHelper.HasCollectionItemIds) to verify ids exist before calling IsItemDeleted.
- Verify the node passed in is the AssetObjectNode for a collection with identifiable items, not a different node type.
- Re-save/migrate the asset so its collection ids metadata is regenerated.
Example fix
// before
bool deleted = nodeExtended.IsItemDeleted(itemId);
// after
if (CollectionItemIdHelper.HasCollectionItemIds(nodeExtended.Node.Retrieve()))
deleted = nodeExtended.IsItemDeleted(itemId);
else
deleted = false; // treat as non-identifiable collection Defensive patterns
Strategy: validation
Validate before calling
bool canQuery = CollectionItemIdHelper.HasCollectionItemIds(nodeExtended.Node.Retrieve()); if (!canQuery) return false; // non-identifiable collection: no deleted ids
Type guard
static bool HasItemIds(AssetObjectNodeExtended n) =>
CollectionItemIdHelper.HasCollectionItemIds(n.Node.Retrieve()); Try / catch
try { deleted = nodeExtended.IsItemDeleted(itemId); }
catch (InvalidOperationException) { deleted = false; // ids missing } Prevention
- Check HasCollectionItemIds before id-based queries
- Avoid NonIdentifiableCollectionItemsAttribute on collections you query by id
- Ensure asset metadata is loaded/upgraded before override checks
When it happens
Trigger: Calling IsItemDeleted (directly or via IsItemOverriddenDeleted) on a node whose Retrieve() returns an object for which TryGetCollectionItemIds fails — i.e. the node's collection has no collection-item-ids metadata (non-identifiable collection, metadata not yet attached, or node type changed).
Common situations: Querying deleted-item state on collections not marked identifiable; calling during partial deserialization before ids are attached; passing a node wrapping a non-collection or a collection stripped of its NonIdentifiableCollectionItemsAttribute metadata; asset edit-vs-base mismatch after type changes.
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
- An item has been added to a collection that does not have a…
- Unable to find the base
- Unable to find the graph corresponding to the base part
- The base is unset for the current node.
- An IObjectNode was expected when processing the path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b152a41637e228eb.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets.Quantum/Internal/AssetObjectNodeExtended.cs:106
}
node.NotifyOverrideChanged();
}
}
public void DisconnectOverriddenDeletedItem(ItemId deletedId)
{
disconnectedDeletedIds.Add(deletedId);
OverrideDeletedItem(false, deletedId);
}
public bool IsItemDeleted(ItemId itemId)
{
if (disconnectedDeletedIds.Contains(itemId))
return true;
var collection = node.Retrieve();
if (!TryGetCollectionItemIds(collection, out var ids))
throw new InvalidOperationException("No Collection item identifier associated to the given collection.");
return ids.IsDeleted(itemId);
}
private bool TryGetCollectionItemIds(object? instance, [MaybeNullWhen(false)] out CollectionItemIdentifiers itemIds)
{
if (collectionItemIdentifiers is not null)
{
itemIds = collectionItemIdentifiers;
return true;
}
var result = CollectionItemIdHelper.TryGetCollectionItemIds(instance, out collectionItemIdentifiers);
itemIds = collectionItemIdentifiers;
return result;
}
public void Restore(object restoredItem, ItemId id)
{View on GitHub (pinned to 96fad776d2)