stride3d/stride · error · SemanticErrorException

Did not find expected <stream-start>.

Error message

Did not find expected <stream-start>.

What it means

The parser's StateMachine calls ParseStreamStart to consume the initial STREAM-START token. If the first token from the scanner is not a StreamStart, the input does not begin as a valid YAML character stream and a SemanticErrorException is thrown at the token's source span.

Solutions

  1. Verify the input is valid YAML text before parsing (encoding, not JSON, not binary)
  2. Parse via YamlStream/YamlDocument instead of driving Parser directly so the stream is set up correctly
  3. Re-create the parser/scanner for a fresh input rather than reusing a consumed one

Example fix

// before
var parser = new Parser(new Scanner(reader));
var evt = parser.ReadYamlEvent(); // throws if first token isn't stream-start
// after
using var rdr = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true);
var stream2 = new YamlStream();
stream2.Load(rdr); // handles stream framing correctly
Defensive patterns

Strategy: try-catch

Validate before calling

var text = File.ReadAllText(path);
if (string.IsNullOrWhiteSpace(text)) throw new InvalidDataException($"{path} is empty");
if (text.TrimStart().StartsWith("{")) throw new InvalidDataException($"{path} looks like JSON, not YAML");

Try / catch

try { stream.Load(reader); } catch (SemanticErrorException ex) { throw new YamlConfigException($"Invalid YAML stream: {ex.Message}", ex); }

Prevention

When it happens

Trigger: Parsing input whose tokenizer did not emit a leading StreamStart — typically malformed or non-YAML content passed to Parser.ReadYamlEvent/Parse, or a parser instance fed tokens out of order.

Common situations: Loading a config file that is actually JSON/binary/empty garbage, reading a file with a UTF-8 BOM handled incorrectly, or scanning an already-partially-consumed stream.

Related errors


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

Appendix: source

Thrown at sources/core/Stride.Core.Yaml/Parser.cs:223

            if (currentToken != null)
            {
                currentToken = null;
                scanner.ConsumeCurrent();
            }
        }

        /// <summary>
        /// Parse the production:
        /// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
        ///              ************
        /// </summary>
        private Event ParseStreamStart()
        {
            StreamStart streamStart = GetCurrentToken() as StreamStart;
            if (streamStart == null)
            {
                var current = GetCurrentToken();
                throw new SemanticErrorException(current.Start, current.End, "Did not find expected <stream-start>.");
            }
            Skip();

            state = ParserState.YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
            return new Events.StreamStart(streamStart.Start, streamStart.End);
        }

        /// <summary>
        /// Parse the productions:
        /// implicit_document    ::= block_node DOCUMENT-END*
        ///                          *
        /// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
        ///                          *************************
        /// </summary>
        private Event ParseDocumentStart(bool isImplicit)
        {
            // Parse extra document end indicators.

View on GitHub (pinned to 96fad776d2)