stride3d/stride · error · SyntaxErrorException

While parsing a quoted scalar, did not find expected…

Error message

While parsing a quoted scalar, did not find expected hexdecimal number.

What it means

Thrown by the YAML Scanner while scanning an escape sequence inside a single/double-quoted scalar (e.g. \x, \u, \U). After the escape indicator the scanner expects exactly codeLength hexadecimal digits; if any position is not a hex digit the escape code is malformed and parsing cannot continue. This is a hard syntax error in the input document, not a runtime condition.

Solutions

  1. Open the file at the reported line/column and complete the escape sequence with the correct number of hex digits (\x needs 2, \u needs 4, \U needs 8).
  2. Remove the backslash if the value was meant literally (YAML only needs escaping for control characters in double-quoted scalars).
  3. Switch the scalar to a plain or single-quoted style so backslashes are treated literally and no escape parsing occurs.
  4. Validate the YAML with a linter (yamllint or an online parser) before loading it in the application.

Example fix

// before (bad input)
title: "Caf\xZZ"
// after
title: "Caf\u00e9"
Defensive patterns

Strategy: validation

Validate before calling

var re = new System.Text.RegularExpressions.Regex("\\\\x[0-9A-Fa-f]{2}|\\\\u[0-9A-Fa-f]{4}|\\\\U[0-9A-Fa-f]{8}");
// Scan the raw YAML text for quoted-scalar escapes before parsing:
bool HasMalformedEscape(string yaml) =>
    System.Text.RegularExpressions.Regex.IsMatch(yaml, "\\\\(x[^0-9A-Fa-f]{2}|x[0-9A-Fa-f]{0,1}[^\\s\"][^\\s]|u[0-9A-Fa-f]{0,3}[^0-9A-Fa-f\\s]|U[0-9A-Fa-f]{0,7}[^0-9A-Fa-f\\s])");

Try / catch

try
{
    var obj = Deserializer.FromFile(path);
}
catch (SyntaxErrorException ex)
{
    // ex shows start/mark with line & column of the bad escape
    Log.Error(ex, "Malformed hex escape in YAML at {Start}", ex.Start);
}

Prevention

When it happens

Trigger: Parsing a YAML stream (Scanner.Scan or higher-level Deserializer) that contains a quoted scalar with a Unicode escape sequence like \x, \u or \U followed by fewer than the required hex digits or a non-hex character, e.g. "\xZZ" or "\u12G4".

Common situations: Hand-edited YAML config files where an escape was truncated by copy-paste; templates that interpolate into string literals leaving a lone backslash before non-hex text; content generated by tools that mix C/JSON escaping rules into YAML.

Related errors


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

Appendix: source

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

                                break;
                        }

                        Skip();
                        Skip();

                        // Consume an arbitrary escape code.

                        if (codeLength > 0)
                        {
                            uint character = 0;

                            // Scan the character value.

                            for (int k = 0; k < codeLength; ++k)
                            {
                                if (!analyzer.IsHex(k))
                                {
                                    throw new SyntaxErrorException(start, mark, "While parsing a quoted scalar, did not find expected hexdecimal number.");
                                }
                                character = (uint) ((character << 4) + analyzer.AsHex(k));
                            }

                            // Check the value and write the character.

                            if ((character >= 0xD800 && character <= 0xDFFF) || character > 0x10FFFF)
                            {
                                throw new SyntaxErrorException(start, mark, "While parsing a quoted scalar, find invalid Unicode character escape code.");
                            }

                            scanScalarValue.Append((char) character);

                            // Advance the pointer.

                            for (int k = 0; k < codeLength; ++k)
                            {
                                Skip();

View on GitHub (pinned to 96fad776d2)