Skip to content

fix(codex): handle SDK TypeError when backend returns output=null - #32939

Closed
HongBoogie wants to merge 1 commit into
NousResearch:mainfrom
HongBoogie:fix/codex-output-null
Closed

fix(codex): handle SDK TypeError when backend returns output=null#32939
HongBoogie wants to merge 1 commit into
NousResearch:mainfrom
HongBoogie:fix/codex-output-null

Conversation

@HongBoogie

Copy link
Copy Markdown

The ChatGPT Codex backend (chatgpt.com/backend-api/codex) can return response.output = null in the
response.completed SSE event. The OpenAI SDK (v2.32+) crashes with TypeError: 'NoneType' object is not
iterable in parse_response() which iterates response.output.

This error surfaces both during the for event in stream: iteration (inside accumulate_event()) and during
get_final_response(). The agent loop catches it as a non-retryable TypeError, aborting the request
entirely — even though the actual response content was already streamed successfully via delta events.

Fix: catch TypeError at both levels in run_codex_stream() and fall back to manual response assembly from
collected output_item.done events or accumulated text deltas.

What does this PR do?

Fixes a crash where the Codex Responses streaming path raises TypeError: 'NoneType' object is not
iterable when the ChatGPT Codex backend returns response.output = null in the response.completed SSE
event. The OpenAI SDK (v2.32+) does not null-check response.output before iterating it in
parse_response(). This PR catches the TypeError at both the stream iteration and get_final_response()
levels, and falls back to assembling the response from already-collected stream events or text deltas.

Related Issue

None — discovered in production logs (Non-retryable error (HTTP None): 'NoneType' object is not
iterable).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • agent/codex_runtime.py: Wrapped for event in stream: loop in try-except TypeError to catch SDK crash
    during response.completed event processing
  • agent/codex_runtime.py: Wrapped stream.get_final_response() in try-except TypeError as a second defense
    layer
  • agent/codex_runtime.py: Added manual response assembly from output_item.done events or accumulated text
    deltas when SDK fails
  • agent/codex_runtime.py: Added import uuid for generating response IDs in manual assembly path

How to Test

  1. Configure hermes with openai-codex provider (model: gpt-5.5)
  2. Send a message via Slack/CLI — the Codex backend intermittently returns output: null in
    response.completed
  3. Before fix: agent crashes with Non-retryable error (HTTP None): 'NoneType' object is not iterable
  4. After fix: response is correctly assembled from stream events and delivered normally

Reproduction script:
from openai import OpenAI
client = OpenAI(api_key="<codex_token>", base_url="https://chatgpt.com/backend-api/codex")
with client.responses.stream(model="gpt-5.5", instructions="hi",
input=[{"role":"user","content":"hello"}], store=False) as stream:
for event in stream: # TypeError crashes here on response.completed
pass

Checklist

Code

Documentation & Housekeeping

  • I've updated relevant documentation — N/A
  • I've updated cli-config.yaml.example — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md — N/A
  • I've considered cross-platform impact — N/A (pure Python, no platform-specific code)
  • I've updated tool descriptions/schemas — N/A

Screenshots / Logs

Before fix:
⚠️ Non-retryable error (HTTP None) — trying fallback...
❌ Non-retryable error (HTTP None): 'NoneType' object is not iterable

After fix:
DEBUG: Codex stream: SDK TypeError during iteration (response.output=null); will assemble manually.
DEBUG: Codex stream: manually assembled response from 1 output items

Response delivered normally

The ChatGPT Codex backend (chatgpt.com/backend-api/codex) can return
`response.output = null` in the `response.completed` SSE event.
The OpenAI SDK (v2.32+) crashes with `TypeError: 'NoneType' object is
not iterable` in `parse_response()` which iterates `response.output`.

This error surfaces both during the `for event in stream:` iteration
(inside `accumulate_event()`) and during `get_final_response()`.
The agent loop catches it as a non-retryable TypeError, aborting the
request entirely — even though the actual response content was already
streamed successfully via delta events.

Fix: catch TypeError at both levels in `run_codex_stream()` and fall
back to manual response assembly from collected `output_item.done`
events or accumulated text deltas.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/openai OpenAI / Codex Responses API duplicate This issue or pull request already exists labels May 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #32884 (canonical) — same Codex Responses null output recovery. Catches TypeError at stream iteration and get_final_response() levels. 10+ competing PRs already open for root cause #11179.

@teknium1

Copy link
Copy Markdown
Contributor

Closing as duplicate — the Codex null-output fix has been merged via #32963 (cherry-picked from @carltonawong's PR #32890, the one Gille reviewed). Thanks for jumping on the outage so quickly; appreciate the help. Closes #11179.

@teknium1 teknium1 closed this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have provider/openai OpenAI / Codex Responses API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants