Skip to content

fix(ssestream): skip dispatching empty events for comment-only SSE blocks#643

Open
jh317729530 wants to merge 1 commit into
openai:mainfrom
jh317729530:fix/ssestream-skip-empty-events
Open

fix(ssestream): skip dispatching empty events for comment-only SSE blocks#643
jh317729530 wants to merge 1 commit into
openai:mainfrom
jh317729530:fix/ssestream-skip-empty-events

Conversation

@jh317729530
Copy link
Copy Markdown

Summary

The eventStreamDecoder.Next() method currently dispatches an event unconditionally whenever it encounters an empty line. This causes issues when SSE keep-alive comments (e.g. : ping) are followed by a blank line — an empty Event (with no type and no data) is dispatched, which leads to a json.Unmarshal error (unexpected end of JSON input) in the upstream Stream[T].Next().

Per the SSE specification:

If the data buffer is an empty string [...] set the data buffer and the event type buffer to the empty string and return.

In other words, if no data: or event: fields were set before the blank line, the event should be silently discarded.

Changes

  • packages/ssestream/ssestream.go: Added a guard in eventStreamDecoder.Next() to continue (instead of dispatching) when an empty line is encountered but both data and event are empty.
  • packages/ssestream/ssestream_test.go: Added comprehensive tests covering:
    • Comment-only blocks (: ping\n\n) produce no events
    • Comments followed by real data events are handled correctly
    • Multiple consecutive comment blocks are all skipped
    • Events with only a type (no data) still dispatch correctly
    • Normal data events and events with both type and data work as before

Reproduction

Send an SSE stream containing:

: ping

data: {"id":"1"}

Before fix: The : ping\n\n block dispatches an empty event → json.Unmarshal([]byte{}, ...) → error.

After fix: The : ping\n\n block is silently skipped, only the data: {"id":"1"} event is dispatched.

Test plan

  • All new unit tests pass (go test ./packages/ssestream/ -v)
  • No existing tests are broken
  • Maintainers verify behavior against real OpenAI streaming endpoints with keep-alive pings

Made with Cursor

…ocks

Per the SSE specification, if the data buffer is empty and the event
type is empty when an empty line is encountered, the event should be
ignored rather than dispatched. Previously, the decoder dispatched an
event unconditionally on every empty line, which caused downstream
json.Unmarshal errors when SSE keep-alive comments like ": ping" were
followed by blank lines.

This change adds a check so that comment-only blocks (e.g. ": ping\n\n")
no longer produce spurious empty events, while still correctly
dispatching events that have either data or an explicit event type set.

Made-with: Cursor
@jh317729530 jh317729530 requested a review from a team as a code owner April 15, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants