stride3d/stride · error · InvalidOperationException

The path [ ] contains a non-valid item id on a collection.

Error message

The path [{ToString()}] contains a non-valid item id on a collection.

What it means

Thrown by YamlAssetPath.ToMemberPath when an ItemId path element resolves against a list (non-set collection) but the key derived from the item id is not an integer. Lists are position-based, so only integer keys are valid; a non-int key means the id is stale or was produced for a keyed container.

Solutions

  1. Re-save the asset so list paths are stored as integer indices/item ids matching the current container type
  2. Migrate the container type or the stored path when refactoring a property between list and set/dictionary
  3. Remove and re-create the affected reference in the editor
  4. Catch InvalidOperationException around ToMemberPath and re-link broken references programmatically

Example fix

// before
myList: !AssetRef itemId="0a1b-..."
// after
myList:
  index: 0
Defensive patterns

Strategy: type-guard

Validate before calling

var key = ids.GetKey(itemId); if (isList && key is not int) throw new ArgumentException("List item ids must resolve to int keys");

Type guard

bool IsIntListItemId(object key) => key is int;

Try / catch

try { memberPath = yamlPath.ToMemberPath(); } catch (InvalidOperationException) { RebuildPathFromObjectGraph(asset, yamlPath); }

Prevention

When it happens

Trigger: In the ElementType.ItemId branch, currentObject's descriptor is a CollectionDescriptor with Category != Set and the resolved key is not int (e.g. a Guid or string from a previous set/dictionary representation).

Common situations: Container type changed between asset versions (e.g. HashSet<T> changed to List<T> or vice versa), leaving GUID-style ids in paths against lists; duplicated/merged assets; hand-edited YAML.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/Yaml/YamlAssetPath.cs:313

                            if (key is not int) throw new InvalidOperationException($"The path [{ToString()}] contains a non-valid item id on an array.");
                            int keyInt = (int)key;
                            memberPath.Push(arrayDescriptor, keyInt);
                            currentObject = arrayDescriptor.GetValue(currentObject, keyInt);
                        }
                        else if (typeDescriptor is CollectionDescriptor collectionDescriptor)
                        {
                            if (collectionDescriptor.Category == DescriptorCategory.Set)
                            {
                                if (item.Value is null && !collectionDescriptor.ElementType.IsNullable())
                                {
                                    throw new InvalidOperationException($"The path [{ToString()}] contains a null item on a set.");
                                }
                            }
                            else
                            {
                                if (key is not int)
                                {
                                    throw new InvalidOperationException($"The path [{ToString()}] contains a non-valid item id on a collection.");
                                }
                            }
                            memberPath.Push(collectionDescriptor, key);
                            currentObject = collectionDescriptor.GetValue(currentObject, key);
                        }
                        else if (typeDescriptor is DictionaryDescriptor dictionaryDescriptor)
                        {
                            if (key is null) throw new InvalidOperationException($"The path [{ToString()}] contains a non-valid item id on an dictionary.");
                            memberPath.Push(dictionaryDescriptor, key);
                            currentObject = dictionaryDescriptor.GetValue(currentObject, key);
                        }
                        break;
                    }
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

View on GitHub (pinned to 96fad776d2)