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
- Re-encode the tag from a .NET string using UTF-8 percent-encoding (Uri.EscapeDataString) so every escape decodes to one char.
- 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).
- Simplify the tag to ASCII characters, which avoids UTF-8 decoding entirely.
- 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
- Never hand-assemble escapes from UTF-16 code units; encode the code point.
- Test any tag generator against non-BMP characters (emoji, rare scripts).
- Prefer ASCII tags in serializable types.
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
- While parsing a tag, find an incorrect leading UTF-8 octet.
- While parsing a tag, find an incorrect trailing UTF-8 octet.
- A serializer factory selector must be sealed before being…
- Aliases are not supported in JSON
- An IMemberNode was expected when processing the path
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)