stride3d/stride · error · YamlException

Expected nothing after STREAM-END

Error message

Expected nothing after STREAM-END

What it means

The emitter's state machine reaches YAML_EMIT_END_STATE after the STREAM-END event has been written; the stream is finished. If another event is then fed to Emit, the emitter throws YamlException because no events may follow STREAM-END.

Solutions

  1. Stop the emission loop when a StreamEnd event has been written.
  2. Create a new Emitter instance for each output stream/document sequence.
  3. Ensure your event source yields exactly one StreamStart ... StreamEnd sequence.

Example fix

// before
foreach (var evt in events) emitter.Emit(evt); // events may extend past StreamEnd
// after
foreach (var evt in events)
{
    emitter.Emit(evt);
    if (evt is StreamEnd) break;
}
Defensive patterns

Strategy: type-guard

Validate before calling

foreach (var evt in events)
{
    emitter.Emit(evt);
    if (evt is StreamEnd) break; // nothing may follow STREAM-END
}

Type guard

bool CanEmit(ParsingEvent evt, bool streamEnded) => !streamEnded || evt is StreamEnd;

Try / catch

try { emitter.Emit(evt); }
catch (YamlException ex) when (ex.Message == "Expected nothing after STREAM-END") { /* drop trailing events; stream already complete */ }

Prevention

When it happens

Trigger: Calling Emitter.Emit with any ParsingEvent after a StreamEnd event has already been emitted.

Common situations: Manual emitter loops that emit documents in a cycle and don't stop after StreamEnd; emitting a second stream on the same emitter; event-producing code that appends trailing events.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at sources/core/Stride.Core.Yaml/Emitter.cs:629

                case EmitterState.YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
                    EmitBlockMappingKey(evt, true);
                    break;

                case EmitterState.YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
                    EmitBlockMappingKey(evt, false);
                    break;

                case EmitterState.YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
                    EmitBlockMappingValue(evt, true);
                    break;

                case EmitterState.YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
                    EmitBlockMappingValue(evt, false);
                    break;

                case EmitterState.YAML_EMIT_END_STATE:
                    throw new YamlException("Expected nothing after STREAM-END");

                default:
                    Debug.Assert(false, "Invalid state.");
                    throw new InvalidOperationException("Invalid state");
            }
        }

        /// <summary>
        /// Expect STREAM-START.
        /// </summary>
        private void EmitStreamStart(ParsingEvent evt)
        {
            if (!(evt is StreamStart))
            {
                throw new ArgumentException("Expected STREAM-START.", "evt");
            }

            indent = -1;

View on GitHub (pinned to 96fad776d2)