stride3d/stride · error · SyntaxErrorException

While parsing a tag, did not find URI escaped octet.

Error message

While parsing a tag, did not find URI escaped octet.

What it means

Inside Scanner.ScanTagUri, a '%' starts a URI-escaped octet in a tag, but the two following characters were not hex digits (e.g. '%G1' or '%' at end of input). Valid URI escapes in YAML tags must be exactly %XX with hex digits, so the scanner throws SyntaxErrorException.

Solutions

  1. Percent-encode '%' in the tag as '%25', e.g. '!100%25done'.
  2. Ensure every '%' in the tag is followed by exactly two hex digits (%2F, %3A, ...).
  3. Remove unintended '%' characters from the tag name.
  4. Catch SyntaxErrorException and report the mark to locate the bad escape.

Example fix

// before (input.yaml)
name: !100%error

// after (input.yaml)
name: !100%25error
Defensive patterns

Strategy: validation

Validate before calling

// C#
foreach (System.Text.RegularExpressions.Match m in System.Text.RegularExpressions.Regex.Matches(yamlText, "%.."))
{
    var hex = m.Value.Substring(1);
    if (!byte.TryParse(hex, System.Globalization.NumberStyles.HexNumber, null, out _))
        throw new FormatException($"Invalid URI escape %{hex} in YAML tag.");
}

Try / catch

try { deserializer.Deserialize(reader, targetType); }
catch (SyntaxErrorException ex) { throw new YamlConfigException($"Invalid % escape in tag at line {ex.Start.Line}", ex); }

Prevention

When it happens

Trigger: Parsing a tag containing an invalid percent-escape, e.g. '!%zzfoo' or '!foo%2' — the character after '%' is not hex, or fewer than two characters remain.

Common situations: Tags containing literal percent signs that were not percent-encoded (e.g. Windows paths like '!C:\100%done'); hand-built tag URIs with truncated escapes; URL-encoding applied incorrectly to tag suffixes.

Related errors


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

Appendix: source

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

            return tag.ToString();
        }

        /// <summary>
        /// Decode an URI-escape sequence corresponding to a single UTF-8 character.
        /// </summary>
        private char ScanUriEscapes(Mark start)
        {
            // Decode the required number of characters.

            List<byte> charBytes = new List<byte>();
            int width = 0;
            do
            {
                // Check for a URI-escaped octet.

                if (!(analyzer.Check('%') && analyzer.IsHex(1) && analyzer.IsHex(2)))
                {
                    throw new SyntaxErrorException(start, mark, "While parsing a tag, did not find URI escaped octet.");
                }

                // Get the octet.

                int octet = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2);

                // If it is the leading octet, determine the length of the UTF-8 sequence.

                if (width == 0)
                {
                    width = (octet & 0x80) == 0x00 ? 1 :
                        (octet & 0xE0) == 0xC0 ? 2 :
                            (octet & 0xF0) == 0xE0 ? 3 :
                                (octet & 0xF8) == 0xF0 ? 4 : 0;

                    if (width == 0)
                    {
                        throw new SyntaxErrorException(start, mark, "While parsing a tag, find an incorrect leading UTF-8 octet.");

View on GitHub (pinned to 96fad776d2)