fix(streaming): move unreachable error event check out of thread. branch#2941
fix(streaming): move unreachable error event check out of thread. branch#2941MaxwellCalkin wants to merge 1 commit intoopenai:mainfrom
Conversation
The `sse.event == "error"` check in both `Stream.__stream__` and
`AsyncStream.__stream__` was nested inside the
`if sse.event.startswith("thread.")` branch, making it dead code
since "error" never starts with "thread.".
This was introduced in commit 48188cc when the branch logic was
refactored to check for `thread.` events first instead of
`response.*`/`transcript.*` events. The error check was left in the
wrong branch, and the subsequent indentation fix in abc2596
preserved the mistake.
The fix moves the error event handling into its own `elif` branch
so it can actually be reached when the server sends an SSE with
`event: error`.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e05a9aca74
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| elif sse.event == "error": | ||
| data = sse.json() | ||
| if is_mapping(data) and data.get("error"): |
There was a problem hiding this comment.
Preserve
event:error items when payload lacks error key
This new elif sse.event == "error" branch no longer yields anything when the payload does not contain a top-level error field, so event:error SSEs can be silently dropped. In Assistants streaming, ErrorEvent is modeled as { "event": "error", "data": ErrorObject } (not {"error": ...}), so this path will skip the APIError raise and also skip process_data, meaning consumers never receive the event; the same regression is duplicated in AsyncStream.__stream__.
Useful? React with 👍 / 👎.
Summary
Fixes #2796.
The
sse.event == "error"check in bothStream.__stream__andAsyncStream.__stream__is dead code — it's nested insideif sse.event.startswith("thread."), but"error"never starts with"thread.".Root cause
This was introduced in commit 48188cc when the branch logic was refactored from checking for
response.*/transcript.*events first to checking forthread.*events first. Thesse.event == "error"check was in theelsebranch (non-response.*events) before the refactor, but was accidentally placed in thethread.*branch after it. The subsequent indentation fix in abc2596 preserved the mistake.Before 48188cc (correct):
After 48188cc (broken):
Fix
Move the error event handling into its own
elif sse.event == "error":branch between thethread.*check and theelsefallback, so it can actually be reached when the server sends an SSE withevent: error.Applied to both
Stream.__stream__(sync) andAsyncStream.__stream__(async).Test plan
elifbranch is reached forevent: errorSSEsthread.*events still handled correctly (no behavior change)elsebranch🤖 Generated with Claude Code