stride3d/stride · error · SyntaxErrorException

While scanning for the next token, find character that…

Error message

While scanning for the next token, find character that cannot start any token.

What it means

The tokenizer encountered a character that cannot begin any YAML token (neither indicator, scalar start, whitespace, nor comment). The scanner's character dispatch fell through all Fetch* branches and threw this SyntaxErrorException.

Solutions

  1. Find the offending character at the reported offset and remove or replace it
  2. Quote the line as a string or strip non-printable bytes (re-save file as UTF-8 without control chars)
  3. Check for BOM or invisible characters with `cat -A` or a hex editor
  4. Replace reserved indicators ('@', '`') at token start with quoted strings

Example fix

// before
@tag: value   # '@' cannot start a token
// after
tag: "@value"
Defensive patterns

Strategy: validation

Validate before calling

// Strip/reject non-printable characters before parsing
foreach (char c in yamlText) if (char.IsControl(c) && c != '\n' && c != '\r' && c != '\t') throw new FormatException($"Control char U+{(int)c:X4} in YAML input");

Type guard

bool IsSafeYamlStart(string s) { var t = s.TrimStart(); return t.Length == 0 || (t[0] != '@' && t[0] != '`'); }

Try / catch

catch (SyntaxErrorException ex) { throw new ConfigFormatException($"Invalid character near offset {ex.Start.Line}:{ex.Start.Column}"); }

Prevention

When it happens

Trigger: A control character, stray '@' or '`' (reserved indicators), or an invalid byte at the start of a token position in the YAML stream.

Common situations: Copy-pasted text carrying invisible control characters, binary data accidentally pasted into a YAML file, or characters like `@tools` at line start which YAML reserves.

Related errors


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

Appendix: source

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

            // The last rule is more restrictive than the specification requires.


            bool isInvalidPlainScalarCharacter = analyzer.IsBlankOrBreakOrZero() || analyzer.Check("-?:,[]{}#&*!|>'\"%@`");

            bool isPlainScalar =
                !isInvalidPlainScalarCharacter ||
                (analyzer.Check('-') && !analyzer.IsBlank(1)) ||
                (flowLevel == 0 && (analyzer.Check("?:")) && !analyzer.IsBlankOrBreakOrZero(1));

            if (isPlainScalar)
            {
                FetchPlainScalar();
                return;
            }

            // If we don't determine the token type so far, it is an error.
            throw new SyntaxErrorException(mark, mark, "While scanning for the next token, find character that cannot start any token.");
        }

        private bool CheckWhiteSpace()
        {
            return analyzer.Check(' ') || ((flowLevel > 0 || !simpleKeyAllowed) && analyzer.Check('\t'));
        }

        private bool IsDocumentIndicator()
        {
            if (mark.Column == 0 && analyzer.IsBlankOrBreakOrZero(3))
            {
                bool isDocumentStart = analyzer.Check('-', 0) && analyzer.Check('-', 1) && analyzer.Check('-', 2);
                bool isDocumentEnd = analyzer.Check('.', 0) && analyzer.Check('.', 1) && analyzer.Check('.', 2);

                return isDocumentStart || isDocumentEnd;
            }
            else
            {

View on GitHub (pinned to 96fad776d2)