stride3d/stride · error · InvalidOperationException

An IMemberNode was expected when processing the path

Error message

An IMemberNode was expected when processing the path [{path}]

What it means

ConvertPath handles a Target step in a GraphNodePath by dereferencing the current member node's target. The current node must be an IMemberNode for that; if it's an object node or something else, the path structure doesn't line up and it throws.

Solutions

  1. Rebuild the path from the live graph instead of deserializing an outdated one.
  2. Check the path structure: Target steps must immediately follow a Member step; fix path construction accordingly.
  3. Verify currentNode is IMemberNode before processing a Target element and skip/repair the path otherwise.
  4. Update stored override paths after asset type refactors.

Example fix

// before
if (i < path.Path.Count - 1)
    currentNode = (IAssetNode?)((IMemberNode)currentNode).Target;
// after
if (currentNode is IMemberNode memberNode)
    currentNode = (IAssetNode?)memberNode.Target;
else
    return null; // unexpected path shape
Defensive patterns

Strategy: type-guard

Validate before calling

bool targetable = path.Path.Zip(prev, (s,p) => s.Type == ElementType.Target && p.Type == ElementType.Member).All(ok);

Type guard

static bool IsMemberTargetStep(IGraphNode n) => n is IMemberNode;

Try / catch

try { result = collector.ConvertPath(path); }
catch (InvalidOperationException) { result = null; }

Prevention

When it happens

Trigger: A GraphNodePath contains a Target element but the node reached so far is not an IMemberNode (e.g. it is already an IObjectNode), so targetingMemberNode.Target cannot be taken — usually from a hand-built or stale path.

Common situations: Path where Target follows an Index or another Target instead of a member; paths saved before an asset type change altered where references live; manually constructed paths for override comparison.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets.Quantum/Visitors/AssetNodeMetadataCollectorBase.cs:87

        var result = new YamlAssetPath();
        var i = 0;
        foreach (var item in path.Path)
        {
            switch (item.Type)
            {
                case GraphNodePath.ElementType.Member:
                {
                    var member = item.Name;
                    result.PushMember(member);
                        if (currentNode is not IObjectNode objectNode) throw new InvalidOperationException($"An IObjectNode was expected when processing the path [{path}]");
                        currentNode = (IAssetNode?)objectNode.TryGetChild(member);
                    break;
                }
                case GraphNodePath.ElementType.Target:
                {
                    if (i < path.Path.Count - 1)
                    {
                            if (currentNode is not IMemberNode targetingMemberNode) throw new InvalidOperationException($"An IMemberNode was expected when processing the path [{path}]");
                            currentNode = (IAssetNode?)targetingMemberNode.Target;
                    }
                    break;
                }
                case GraphNodePath.ElementType.Index:
                {
                    var index = item.Index;
                        if (currentNode is not AssetObjectNode objectNode) throw new InvalidOperationException($"An IObjectNode was expected when processing the path [{path}]");
                        if (inNonIdentifiableType > 0 || !CollectionItemIdHelper.HasCollectionItemIds(objectNode.Retrieve()))
                    {
                        result.PushIndex(index.Value);
                    }
                    else
                    {
                        var id = objectNode.IndexToId(index);
                        // Create a new id if we don't have any so far
                        if (id == ItemId.Empty)
                            id = ItemId.New();

View on GitHub (pinned to 96fad776d2)