stride3d/stride · error · SyntaxErrorException

While scanning a tag, did not find the expected '>'.

Error message

While scanning a tag, did not find the expected '>'.

What it means

When the Scanner encounters a verbatim tag of the form '!<suffix>' (ScanTag), it scans the URI inside the angle brackets and then requires a closing '>'. If the input stream ends, or a non-'>' character appears where the closing bracket should be, this SyntaxErrorException is thrown.

Solutions

  1. Add the missing '>' to close the verbatim tag: '!<tag:example.com,2000:app/foo>'.
  2. Verify the tag is not empty after '!<' — verbatim tags require at least a '/' suffix if using the primary namespace.
  3. Check the reported line for truncation from editors, diff tools, or copy-paste that dropped the trailing '>'.
  4. If you do not need a verbatim tag, use a simple tag shorthand like '!Foo' or a %TAG directive instead.
  5. Validate the document with a YAML parser/linter before loading to catch unbalanced tag delimiters.

Example fix

// before (missing closing '>')
value: !<tag:example.com,2000:thing

// after
value: !<tag:example.com,2000:thing>
Defensive patterns

Strategy: validation

Validate before calling

static bool HasBalancedVerbatimTags(string yaml)
{
    for (int i = yaml.IndexOf("!<"); i >= 0; i = yaml.IndexOf("!<", i + 1))
    {
        int close = yaml.IndexOf('>', i);
        if (close < 0 || close == i + 2) return false; // no '>' or empty tag
    }
    return true;
}

Try / catch

try
{
    yamlStream.Load(reader);
}
catch (YamlException ex)
{
    throw new FormatException($"Malformed verbatim tag near {ex.Start.Line}:{ex.Start.Column}: {ex.Message}", ex);
}

Prevention

When it happens

Trigger: A tag directive-style value written as '!<tag:example.com,2000:app/foo' without the closing '>', or '!<>' with an empty suffix path, or a truncated stream where the '>' was cut off. Reached whenever the tokenizer processes '!<...' input via Deserialize/Load.

Common situations: Hand-written custom tags missing the closing bracket, minification/line-wrapping tools that split '!<...>' across lines or dropped the '>' during copy-paste, and YAML produced by code that builds verbatim tags via string concatenation.

Related errors


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

Appendix: source

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

            {
                // Set the handle to ''

                handle = string.Empty;

                // Eat '!<'

                Skip();
                Skip();

                // Consume the tag value.

                suffix = ScanTagUri(null, start);

                // Check for '>' and eat it.

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

                Skip();
            }
            else
            {
                // The tag has either the '!suffix' or the '!handle!suffix' form.

                // First, try to scan a handle.

                string firstPart = ScanTagHandle(false, start);

                // Check if it is, indeed, handle.

                if (firstPart.Length > 1 && firstPart[0] == '!' && firstPart[firstPart.Length - 1] == '!')
                {
                    handle = firstPart;

View on GitHub (pinned to 96fad776d2)