{"record":{"id":"a69f927e0b741991","repo":"stride3d/stride","slug":"while-parsing-a-node-find-undefined-tag-handle","errorCode":null,"errorMessage":"While parsing a node, find undefined tag handle.","messagePattern":"While parsing a node, find undefined tag handle\\.","errorType":"exception","errorClass":"SemanticErrorException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Yaml/Parser.cs","lineNumber":475,"sourceCode":"                {\n                    break;\n                }\n            }\n\n            string tagName = null;\n            if (tag != null)\n            {\n                if (string.IsNullOrEmpty(tag.Handle))\n                {\n                    tagName = tag.Suffix;\n                }\n                else if (tagDirectives.Contains(tag.Handle))\n                {\n                    tagName = string.Concat(tagDirectives[tag.Handle].Prefix, tag.Suffix);\n                }\n                else\n                {\n                    throw new SemanticErrorException(tag.Start, tag.End, \"While parsing a node, find undefined tag handle.\");\n                }\n            }\n            if (string.IsNullOrEmpty(tagName))\n            {\n                tagName = null;\n            }\n\n            string anchorName = anchor != null ? string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value : null;\n\n            bool isImplicit = string.IsNullOrEmpty(tagName);\n\n            if (isIndentlessSequence && GetCurrentToken() is BlockEntry)\n            {\n                state = ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;\n\n                return new Events.SequenceStart(\n                    anchorName,\n                    tagName,","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Yaml/Parser.cs#L457-L493","documentation":"When a node carries a tag using a handle like '!e!suffix', the parser resolves the handle against the document's %TAG directives (plus default handles !! and !). If the handle was never declared and is not a default, ParseNode throws SemanticErrorException at the tag's span.","triggerScenarios":"A node tagged with a custom handle that has no matching %TAG directive, e.g. \"key: !foo! bar\" with no \"%TAG !foo! ...\" line in the document.","commonSituations":"Copy-pasting YAML from docs that assumed %TAG declarations elsewhere, splitting a multi-document file and losing the directives document, hand-editing tags with custom handles.","solutions":["Add the missing %TAG directive at the top of the document (e.g. %TAG !foo! tag:example.com,2000:)","Use the default handle instead: replace '!foo!suffix' with '!!suffix' for standard tags","Use a local tag '!suffix' which requires no directive"],"exampleFix":"// before\n%YAML 1.1\n---\nkey: !foo! value\n// after\n%YAML 1.1\n%TAG !foo! tag:example.com,2000:\n---\nkey: !foo! value","handlingStrategy":"validation","validationCode":"// collect declared handles first\nvar handles = new HashSet<string> { \"!!\", \"!\" };\nforeach (var line in File.ReadLines(path))\n    if (line.StartsWith(\"%TAG \")) handles.Add(line.Split(' ')[1]);\n// then scan node tags like !foo!suffix\nforeach (Match m in Regex.Matches(text, @\"!(\\w+)(?=\" + \"!\" + @\")\"))\n    if (!handles.Contains(\"!\" + m.Groups[1].Value + \"!\")) throw new InvalidDataException($\"Undeclared tag handle !{m.Groups[1].Value}!\");","typeGuard":null,"tryCatchPattern":"try { stream.Load(reader); } catch (SemanticErrorException ex) when (ex.Message.Contains(\"undefined tag handle\")) { throw new YamlConfigException($\"Tag handle not declared via %TAG: {ex.Message}\", ex); }","preventionTips":["Declare every custom tag handle with a %TAG directive","Prefer local tags (!suffix) or standard !!type tags in configs","Keep %TAG directives in the same file/document as their usage"],"tags":["yaml","tag","parser","undefined-handle"],"backgroundTag":"yaml-parse-error","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"}