Skip to content

fix(responses): handle null output in parse_response - #3586

Open
mayuriphad wants to merge 1 commit into
openai:mainfrom
mayuriphad:fix/parse-response-null-output
Open

fix(responses): handle null output in parse_response#3586
mayuriphad wants to merge 1 commit into
openai:mainfrom
mayuriphad:fix/parse-response-null-output

Conversation

@mayuriphad

Copy link
Copy Markdown

Summary

Some backends (e.g. the chatgpt.com Codex backend used by the Codex CLI) can send output: null on the response.completed event, even though the schema declares output as a non-nullable list. This crashes parse_response() in src/openai/lib/_parsing/_responses.py with:

TypeError: 'NoneType' object is not iterable

This kills the entire stream before the consumer can read any already-accumulated deltas, even when valid response.output_item.done events were seen earlier in the same response.

Fix

Coerce a null response.output to an empty list before iterating in parse_response(), so streams complete and get_final_response() returns a Response/ParsedResponse with output=[] instead of crashing. Consumers that already track output_item.done events can backfill from their own collected items.

Test plan

  • Added test_parse_response_with_null_output in tests/lib/responses/test_responses.py, which constructs a Response with output=None and asserts parse_response() returns output=[] instead of raising.
  • Verified the new test fails with TypeError: 'NoneType' object is not iterable on the pre-fix code, and passes after the fix.
  • Ran tests/lib/responses/ locally: all tests pass.
  • Ran ruff check on the changed files: no issues.

Fixes #3325

Some backends (e.g. the chatgpt.com Codex backend used by the Codex
CLI) can send `output: null` on the `response.completed` event even
though the schema declares `output` as a non-nullable list. This
caused parse_response() to raise `TypeError: 'NoneType' object is not
iterable`, killing the entire stream before consumers could read
already-accumulated deltas.

Coerce a null output to an empty list before iterating, matching the
behavior implied by get_final_response() returning an otherwise valid
Response/ParsedResponse.

Fixes openai#3325
Copilot AI lite review requested due to automatic review settings August 9, 2026 17:38
@mayuriphad
mayuriphad requested a review from a team as a code owner August 9, 2026 17:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b34be89cf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

output_list: List[ParsedResponseOutputItem[TextFormatT]] = []

for output in response.output:
for output in response.output or []:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve accumulated stream output on null completion

When using responses.stream() against a backend that sends response.completed.response.output = null after prior response.output_item.added / text-delta events, this fallback makes parse_response() treat the completed response as having no output. ResponseStreamState has already accumulated those items in its snapshot, so get_final_response().output and output_text become empty even though the stream delivered content; the null-completion path should parse the accumulated snapshot rather than unconditionally replacing it with [].

Useful? React with 👍 / 👎.

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.

parse_response crashes with TypeError when response.output is null in response.completed event (chatgpt.com Codex backend)

2 participants