fix: tolerate null response output when parsing responses#3316
fix: tolerate null response output when parsing responses#3316jin-castle wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f310209b62
ℹ️ 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".
| output_list: List[ParsedResponseOutputItem[TextFormatT]] = [] | ||
|
|
||
| for output in response.output: | ||
| for output in response.output or []: |
There was a problem hiding this comment.
Preserve streamed output when terminal output is null
When a streamed response has already accumulated response.output_item.* / text events but the terminal response.completed payload has response.output is None, this fallback causes parse_response() to return a completed ParsedResponse with output=[]. I checked the streaming path in src/openai/lib/streaming/responses/_responses.py: ResponseStreamState.accumulate_event() assigns _completed_response = parse_response(... response=event.response ...), and get_final_response() returns that object rather than the accumulated snapshot, so callers lose all streamed content instead of just avoiding the TypeError.
Useful? React with 👍 / 👎.
|
Thanks for jumping on this. This looks like a duplicate of the earlier upstream fix PR: Your PR covers the I compared the diffs and did not see an additional behavior change here that needs to be pulled into #3315. |
|
Update: the automated Codex review here identified a useful stream-state data-loss risk. I pulled that into the earlier PR #3315. #3315 now preserves the accumulated So this PR remains a duplicate of #3315, but the useful review finding from this thread is now incorporated there. |
|
Confirming production impact: this regression broke every Traceback for reference: Applied the one-line guard ( |
|
Independent confirmation from the Hermes/Codex side — this Reproduced identically against Two extra data points that may help confirm this is the right layer to fix:
Verified end-to-end: applying exactly this one-liner makes |
|
+1, independently reproduced this against the live The Codex backend can complete a stream with reasoning-only / tool-call-only output, after which the terminal Workaround I'm running locally while this lands: a runtime Diff in this PR matches what I patched directly in |
Summary
Handle Responses objects whose
outputisNonewhen parsing Responses API results.A live downstream regression in Hermes/Codex surfaced this path: the backend can stream usable output events, then the terminal Responses object may deserialize with
response.output is None.parse_response()currently iteratesresponse.outputdirectly and raisesTypeError: 'NoneType' object is not iterablebefore callers can recover from streamed events.This keeps parsing defensive by treating null output like an empty output list.
Related downstream report: NousResearch/hermes-agent#32883
Tests
Also ran: