stride3d/stride · error · InvalidOperationException

The path [ ] contains access to non-existing member [ ].

Error message

The path [{ToString()}] contains access to non-existing member [{name}].

What it means

YamlAssetPath.ToMemberPath looks up each Member element in the current object's type descriptor. If no member with that name exists, it throws InvalidOperationException('The path [...] contains access to non-existing member [name].') — the recorded path no longer matches the object's schema.

Solutions

  1. Update or regenerate the stored paths for the new schema (write an upgrader mapping old member names to new ones)
  2. Verify each member exists via TypeDescriptorFactory.Default.Find(type).Members before resolving
  3. Handle the exception per-path: catch it, log, and skip metadata for that path
  4. Use the MemberSerialization upgrade/renaming support so old paths are migrated on load

Example fix

// before
var memberPath = path.ToMemberPath(asset); // throws if member renamed
// after
try { var memberPath = path.ToMemberPath(asset); }
catch (InvalidOperationException) { logger.Warn($"Stale path skipped: {path}"); }
Defensive patterns

Strategy: try-catch

Validate before calling

var td = TypeDescriptorFactory.Default.Find(root.GetType());
bool exists = path.Elements
    .Where(e => e.Type == YamlAssetPath.ElementType.Member)
    .All(e => td.Members.Any(m => m.Name == e.AsMember()));

Try / catch

try { var mp = path.ToMemberPath(root); }
catch (InvalidOperationException ex) { logger.Warn(ex, $"Stale schema path skipped: {path}"); }

Prevention

When it happens

Trigger: Calling ToMemberPath(root) with a path containing a member name absent from the runtime type — typically after renaming or deleting a property in an asset type between versions.

Common situations: Asset-upgrade scripts applying old-version paths to new-version objects; typos in hand-built YamlAssetPath; serialized metadata from a different project schema version.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

    /// <returns>An instance of <see cref="MemberPath"/> corresponding to the same target than this <see cref="YamlAssetPath"/>.</returns>
    [Pure]
    public MemberPath ToMemberPath(object root)
    {
        var currentObject = root;
        var memberPath = new MemberPath();
        foreach (var item in Elements)
        {
            if (currentObject is null)
                throw new InvalidOperationException($"The path [{ToString()}] contains access to a member of a null object.");

            switch (item.Type)
            {
                case ElementType.Member:
                    {
                        var typeDescriptor = TypeDescriptorFactory.Default.Find(currentObject.GetType());
                        var name = item.AsMember();
                        var memberDescriptor = typeDescriptor.Members.FirstOrDefault(x => x.Name == name)
                            ?? throw new InvalidOperationException($"The path [{ToString()}] contains access to non-existing member [{name}].");
                        memberPath.Push(memberDescriptor);
                        currentObject = memberDescriptor.Get(currentObject);
                        break;
                    }
                case ElementType.Index:
                    {
                        var typeDescriptor = TypeDescriptorFactory.Default.Find(currentObject.GetType());
                        if (typeDescriptor is ArrayDescriptor arrayDescriptor)
                        {
                            if (item.Value is not int)
                            {
                                throw new InvalidOperationException($"The path [{ToString()}] contains non-integer index on an array.");
                            }
                            int value = (int)item.Value;
                            memberPath.Push(arrayDescriptor, value);
                            currentObject = arrayDescriptor.GetValue(currentObject, value);
                        }
                        else if (typeDescriptor is CollectionDescriptor collectionDescriptor)

View on GitHub (pinned to 96fad776d2)