stride3d/stride · error · SyntaxErrorException

While parsing a tag, find an incorrect UTF-8 sequence.

Error message

While parsing a tag, find an incorrect UTF-8 sequence.

What it means

After collecting the octets of one URI-escaped character in a tag (Scanner.ScanTagUri), the scanner decodes them with Encoding.UTF8.GetChars. If the bytes do not decode to exactly one char, the escape did not represent a single valid Unicode character, so it throws SyntaxErrorException.

Solutions

  1. Re-encode the tag from a .NET string using UTF-8 percent-encoding (Uri.EscapeDataString) so every escape decodes to one char.
  2. Replace surrogate-half escapes with the proper 4-byte UTF-8 encoding of the code point (e.g. %F0%90%80%80 for U+10000).
  3. Simplify the tag to ASCII characters, which avoids UTF-8 decoding entirely.
  4. Catch SyntaxErrorException and log the mark plus the raw tag text.

Example fix

// before: tag contains bytes of a UTF-16 surrogate half '!%EDA0%BD'
// after: encode the code point in UTF-8 '!%F0%90%80%BD' or avoid non-ASCII in tags
Defensive patterns

Strategy: validation

Try / catch

try { deserializer.Deserialize(reader, targetType); }
catch (SyntaxErrorException ex) { throw new YamlConfigException($"Tag escape does not encode a single valid character at line {ex.Start.Line}", ex); }

Prevention

When it happens

Trigger: A tag's %XX sequence decodes to zero characters or multiple characters (surrogate pairs or overlong/invalid sequences), e.g. an escape for a UTF-16 surrogate half like '%EDA0%80'.

Common situations: Encoding UTF-16 surrogate pairs byte-by-byte instead of the scalar value; overlong UTF-8 encodings; tools that escaped each byte of non-UTF-8 encodings (UTF-16/UTF-32) into tags.

Related errors


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

Appendix: source

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

                    {
                        throw new SyntaxErrorException(start, mark, "While parsing a tag, find an incorrect trailing UTF-8 octet.");
                    }
                }

                // Copy the octet and move the pointers.

                charBytes.Add((byte) octet);

                Skip();
                Skip();
                Skip();
            } while (--width > 0);

            char[] characters = Encoding.UTF8.GetChars(charBytes.ToArray());

            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.

View on GitHub (pinned to 96fad776d2)