{"record":{"id":"651f6418850b552e","repo":"stride3d/stride","slug":"unknown-node-type","errorCode":null,"errorMessage":"Unknown node type","messagePattern":"Unknown node type","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Yaml/ErrorRecoverySerializer.cs","lineNumber":90,"sourceCode":"                        tag = firstNode.Tag;\n\n                    // Temporarily recreate the node without its tag, so that we can try deserializing as many members as possible still\n                    // TODO: Replace this with switch pattern matching (C# 7.0)\n                    if (firstNode is MappingStart mappingStart)\n                    {\n                        memoryParser.ParsingEvents[startPosition] = new MappingStart(mappingStart.Anchor, null, mappingStart.IsImplicit, mappingStart.Style, mappingStart.Start, mappingStart.End);\n                    }\n                    else if (firstNode is SequenceStart sequenceStart)\n                    {\n                        memoryParser.ParsingEvents[startPosition] = new SequenceStart(sequenceStart.Anchor, null, sequenceStart.IsImplicit, sequenceStart.Style, sequenceStart.Start, sequenceStart.End);\n                    }\n                    else if (firstNode is Scalar scalar)\n                    {\n                        memoryParser.ParsingEvents[startPosition] = new Scalar(scalar.Anchor, null, scalar.Value, scalar.Style, scalar.IsPlainImplicit, scalar.IsQuotedImplicit, scalar.Start, scalar.End);\n                    }\n                    else\n                    {\n                        throw new NotImplementedException(\"Unknown node type\");\n                    }\n                }\n\n                string? typeName = null;\n                string? assemblyName = null;\n                if (tag != null)\n                {\n                    var tagAsType = tag.StartsWith('!') ? tag[1..] : tag;\n                    objectContext.SerializerContext.ParseType(tagAsType, out typeName, out assemblyName);\n                }\n\n                var log = objectContext.SerializerContext.Logger;\n                log?.Warning($\"Could not deserialize object of type '{typeName ?? tag}'; replacing it with an object implementing {nameof(IUnloadable)}\", ex);\n\n                var unloadableObject = UnloadableObjectInstantiator.CreateUnloadableObject(type, typeName, assemblyName, ex.Message, parsingEvents);\n                objectContext.Instance = unloadableObject;\n                objectContext.Descriptor = objectContext.SerializerContext.FindTypeDescriptor(unloadableObject.GetType());\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Yaml/ErrorRecoverySerializer.cs#L72-L108","documentation":"ErrorRecoverySerializer scans YAML parsing events to recover type/assembly tags from errored nodes; when the first node is neither a Mapping, Sequence nor Scalar it throws NotImplementedException('Unknown node type'). The recovery path simply has no handling for that node kind.","triggerScenarios":"ReadYaml encountering a YAML document whose first event is an anchor/alias or other exotic node type (not mapping, sequence, or scalar) during error recovery of a malformed asset.","commonSituations":"Corrupted or hand-edited Stride asset YAML containing aliases/anchors at the document root; a parser producing unexpected event streams after partial reads; assets saved by a newer Stride/YamlDotNet emitting node kinds the recovery code predates.","solutions":["Fix the YAML source so the root node is a mapping, sequence, or scalar (remove root-level anchors/aliases)","Re-export or regenerate the asset from Stride instead of repairing the YAML manually","Check YamlDotNet/Stride version compatibility between the tool that wrote the asset and the reader","Extend ErrorRecoverySerializer to handle the missing node kind if you own the pipeline"],"exampleFix":"# before (root alias, unsupported)\n&base object\n\n# after (plain mapping root)\nroot:\n  Key: value","handlingStrategy":"validation","validationCode":"using var parser = new YamlMappingNode(...); // ensure root is a mapping/sequence/scalar\nif (doc.RootNode is YamlAliasNode) throw new InvalidOperationException(\"Root alias unsupported\");","typeGuard":"bool HasSupportedRoot(YamlDocument doc) =>\n    doc.RootNode is YamlMappingNode or YamlSequenceNode or YamlScalarNode;","tryCatchPattern":"try { return errorRecoverySerializer.ReadYaml(parser, expectedType); }\ncatch (NotImplementedException ex) { logger.Error(ex, \"Unsupported YAML root node during error recovery\"); return null; }","preventionTips":["Keep document roots as plain mappings in asset YAML","Avoid anchors/aliases at the root of asset files","Keep Stride/YamlDotNet versions aligned between writer and reader"],"tags":["yaml","deserialization","not-implemented","error-recovery"],"backgroundTag":"method-not-implemented","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"}