stride3d/stride · error · SyntaxErrorException

While scanning a tag, did not find expected '!'.

Error message

While scanning a tag, did not find expected '!'.

What it means

Scanner.ScanTagHandle requires a tag handle to begin with '!'. When the scanner decides the next token is a tag but the current character is not '!', the internal tokenization invariant is violated for this input and it throws SyntaxErrorException. Effectively this means the YAML text has a malformed tag construct at that position.

Solutions

  1. Inspect the input at the reported line/column and restore the '!' of the tag handle (e.g. '!<tag:yaml.org,2002:str>').
  2. Fix any earlier syntax error that put the scanner in the wrong state — the reported mark may be downstream of the real problem.
  3. Validate the file with a standard YAML parser before loading.
  4. Catch SyntaxErrorException to fail gracefully and surface the position to the user.

Example fix

// before (input.yaml)
%TAG tag:yaml.org,2002: type

// after (input.yaml)
%TAG !tag! tag:yaml.org,2002:
Defensive patterns

Strategy: try-catch

Validate before calling

// C#
if (!string.IsNullOrEmpty(yamlText) && yamlText.Contains("%TAG"))
{
    foreach (var line in yamlText.Split('\n').Where(l => l.StartsWith("%TAG")))
        if (!line.Contains("!")) throw new FormatException($"%TAG directive missing '!': {line.Trim()}");
}

Try / catch

try { deserializer.Deserialize(reader, targetType); }
catch (SyntaxErrorException ex) { throw new YamlConfigException($"Malformed tag handle at line {ex.Start.Line}, col {ex.Start.Column}", ex); }

Prevention

When it happens

Trigger: Input where a tag was detected (e.g. after '&' anchor parsing or in a %TAG directive position) but the character at the mark is not '!', such as corrupted input or an off-by-position state from earlier malformed syntax.

Common situations: Corrupted or machine-mangled YAML; a tag directive line like '%TAG foo bar' missing the '!' in the handle; mixing dialects/editors that mangle '!' characters.

Related errors


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

Appendix: source

Thrown at sources/core/Stride.Core.Yaml/Scanner.cs:2222

            if (characters.Length != 1)
            {
                throw new SyntaxErrorException(start, mark, "While parsing a tag, find an incorrect UTF-8 sequence.");
            }

            return characters[0];
        }

        /// <summary>
        /// Scan a tag handle.
        /// </summary>
        private string ScanTagHandle(bool isDirective, Mark start)
        {
            // Check the initial '!' character.

            if (!analyzer.Check('!'))
            {
                throw new SyntaxErrorException(start, mark, "While scanning a tag, did not find expected '!'.");
            }

            // Copy the '!' character.

            StringBuilder tagHandle = new StringBuilder();
            tagHandle.Append(ReadCurrentCharacter());

            // Copy all subsequent alphabetical and numerical characters.

            while (analyzer.IsAlpha())
            {
                tagHandle.Append(ReadCurrentCharacter());
            }

            // Check if the trailing character is '!' and copy it.

            if (analyzer.Check('!'))
            {

View on GitHub (pinned to 96fad776d2)