{"record":{"id":"86dc6ea883a01ed2","repo":"stride3d/stride","slug":"an-imembernode-was-expected-when-processing-the-path-path-86dc6e","errorCode":null,"errorMessage":"An IMemberNode was expected when processing the path [{path}]","messagePattern":"An IMemberNode was expected when processing the path \\[(.+?)\\]","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets.Quantum/Visitors/AssetNodeMetadataCollectorBase.cs","lineNumber":87,"sourceCode":"        var result = new YamlAssetPath();\n        var i = 0;\n        foreach (var item in path.Path)\n        {\n            switch (item.Type)\n            {\n                case GraphNodePath.ElementType.Member:\n                {\n                    var member = item.Name;\n                    result.PushMember(member);\n                        if (currentNode is not IObjectNode objectNode) throw new InvalidOperationException($\"An IObjectNode was expected when processing the path [{path}]\");\n                        currentNode = (IAssetNode?)objectNode.TryGetChild(member);\n                    break;\n                }\n                case GraphNodePath.ElementType.Target:\n                {\n                    if (i < path.Path.Count - 1)\n                    {\n                            if (currentNode is not IMemberNode targetingMemberNode) throw new InvalidOperationException($\"An IMemberNode was expected when processing the path [{path}]\");\n                            currentNode = (IAssetNode?)targetingMemberNode.Target;\n                    }\n                    break;\n                }\n                case GraphNodePath.ElementType.Index:\n                {\n                    var index = item.Index;\n                        if (currentNode is not AssetObjectNode objectNode) throw new InvalidOperationException($\"An IObjectNode was expected when processing the path [{path}]\");\n                        if (inNonIdentifiableType > 0 || !CollectionItemIdHelper.HasCollectionItemIds(objectNode.Retrieve()))\n                    {\n                        result.PushIndex(index.Value);\n                    }\n                    else\n                    {\n                        var id = objectNode.IndexToId(index);\n                        // Create a new id if we don't have any so far\n                        if (id == ItemId.Empty)\n                            id = ItemId.New();","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets.Quantum/Visitors/AssetNodeMetadataCollectorBase.cs#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rebuild the path from the live graph instead of deserializing an outdated one.","Check the path structure: Target steps must immediately follow a Member step; fix path construction accordingly.","Verify currentNode is IMemberNode before processing a Target element and skip/repair the path otherwise.","Update stored override paths after asset type refactors."],"exampleFix":"// before\nif (i < path.Path.Count - 1)\n    currentNode = (IAssetNode?)((IMemberNode)currentNode).Target;\n// after\nif (currentNode is IMemberNode memberNode)\n    currentNode = (IAssetNode?)memberNode.Target;\nelse\n    return null; // unexpected path shape","handlingStrategy":"type-guard","validationCode":"bool targetable = path.Path.Zip(prev, (s,p) => s.Type == ElementType.Target && p.Type == ElementType.Member).All(ok);","typeGuard":"static bool IsMemberTargetStep(IGraphNode n) => n is IMemberNode;","tryCatchPattern":"try { result = collector.ConvertPath(path); }\ncatch (InvalidOperationException) { result = null; }","preventionTips":["Ensure Target steps follow Member steps in built paths","Reconstruct paths when asset types change","Unit-test path builders against current type graphs"],"tags":["stride","quantum","assets","paths","graph"],"backgroundTag":"incompatible-source-type","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}