Skip to content

fix: handle mid-stream error events in OpenAI SSE streaming#8031

Merged
DOsinga merged 3 commits intomainfrom
fix/handle-sse-error-events
Mar 20, 2026
Merged

fix: handle mid-stream error events in OpenAI SSE streaming#8031
DOsinga merged 3 commits intomainfrom
fix/handle-sse-error-events

Conversation

@DOsinga
Copy link
Copy Markdown
Collaborator

@DOsinga DOsinga commented Mar 20, 2026

Picks up #8027 from @spitfire55 and adds three improvements:

  1. Eliminate double-parse — parse JSON to Value once, then use serde_json::from_value for StreamingChunk rather than calling from_str a second time on the happy path.

  2. Handle vLLM error format — in addition to the OpenAI/SGLang/Exo shape {"error": {"message": "..."}}, also detect vLLM's top-level shape {"object": "error", "message": "..."}.

  3. Add tests — three new async tests using a run_streaming_test_expecting_error helper that drives response_to_streaming_message with a mid-stream error line and asserts the error message propagates correctly:

    • OpenAI/SGLang/Exo format
    • vLLM format
    • Error as the very first chunk (no prior content)

Closes #8027

Clyde and others added 3 commits March 20, 2026 00:22
When an OpenAI-compatible server sends an error object mid-stream
(e.g. {"error": {"message": "..."}}) the deserializer would fail
trying to parse it as a StreamingChunk, crashing with "Stream decode
error". This format is used by vLLM, SGLang, Exo, and OpenAI itself.

Check for an error key before attempting StreamingChunk deserialization,
matching the pattern used by the official OpenAI Python client.

Closes #8021

Signed-off-by: Clyde <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Parse JSON to Value once, then use from_value for StreamingChunk
  to avoid deserializing the same bytes twice on the happy path
- Detect vLLM's error shape: {"object":"error", "message":"..."}
  in addition to OpenAI/SGLang/Exo {"error":{"message":"..."}}
- Add three tests covering OpenAI format, vLLM format, and error-as-
  first-chunk via a run_streaming_test_expecting_error helper

Signed-off-by: Douwe Osinga <[email protected]>
- parse_streaming_chunk returns ProviderError directly, using ServerError
  for mid-stream error payloads instead of a generic anyhow error
- call site in openai_compatible downcasts to ProviderError before
  fallback-wrapping, so the error prefix is never doubled
- drop trivial format comments from parse_streaming_chunk
- collapse three separate async tests into one test_case table

Signed-off-by: Douwe Osinga <[email protected]>
@DOsinga DOsinga added this pull request to the merge queue Mar 20, 2026
Merged via the queue into main with commit 4ed475c Mar 20, 2026
23 checks passed
@DOsinga DOsinga deleted the fix/handle-sse-error-events branch March 20, 2026 14:21
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
Signed-off-by: Clyde <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Clyde <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
Signed-off-by: Clyde <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Clyde <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
* origin/main: (62 commits)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  docs: add Claude Code approve mode permission routing documentation (#7949)
  chatgpt_codex: Support reasoning and gpt-5.4 (#7941)
  refactor(anthropic): fix N+1 thinking message storage issue (#7958)
  fix: handle mid-stream error events in OpenAI SSE streaming (#8031)
  Fix apps extension: coerce string arguments from inner LLM responses (#8030)
  feat: ability to expand sidebar to see chats names  (#7816)
  Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940)
  set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947)
  ...
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
…pstream

* wpfleger/socket-support: (62 commits)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  docs: add Claude Code approve mode permission routing documentation (#7949)
  chatgpt_codex: Support reasoning and gpt-5.4 (#7941)
  refactor(anthropic): fix N+1 thinking message storage issue (#7958)
  fix: handle mid-stream error events in OpenAI SSE streaming (#8031)
  Fix apps extension: coerce string arguments from inner LLM responses (#8030)
  feat: ability to expand sidebar to see chats names  (#7816)
  Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940)
  set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947)
  ...
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