Skip to content

fix(agent): guard openai parse_response against null response.output - #33579

Closed
marcelopaniza wants to merge 1 commit into
NousResearch:mainfrom
marcelopaniza:fix/openai-parse-response-none-guard
Closed

fix(agent): guard openai parse_response against null response.output#33579
marcelopaniza wants to merge 1 commit into
NousResearch:mainfrom
marcelopaniza:fix/openai-parse-response-none-guard

Conversation

@marcelopaniza

Copy link
Copy Markdown

Why

0.14.0 crashes on chatgpt.com/backend-api/codex with TypeError: 'NoneType' object is not iterable when the backend returns response.output: null. Tracked in #33578.

agent/codex_runtime.py on main is already structurally immune — it never reads response.completed.response.output for content. But any caller still on the high-level responses.stream(...) / responses.parse(...) helpers (third-party plugins, future provider profiles, regressions) remains exposed to the same SDK bug as long as openai==2.24.0 is pinned.

What

  • agent/_openai_compat.py — wraps openai.lib._parsing._responses.parse_response. If the incoming response.output is None, it's coerced to [] before delegating to the original function. The wrapper re-binds the symbol in the two SDK modules that imported it by name (openai.lib.streaming.responses._responses, openai.resources.responses.responses) so already-loaded code paths pick up the guard.
  • agent/__init__.py — imports _openai_compat so installation happens on first agent use, before any provider profile is exercised.
  • tests/agent/test_openai_compat.py — three tests: module importable, guard active on the canonical symbol, streaming/resource modules use the guarded reference.

Scope

Test

pytest tests/agent/test_openai_compat.py \
       tests/agent/test_auxiliary_client.py \
       tests/run_agent/test_codex_xai_oauth_recovery.py \
       tests/run_agent/test_streaming.py

→ 263 passed locally (Python 3.14.4 / openai==2.24.0).

Refs: #33578, openai/openai-python#3322, openai/openai-python#3316, openai/openai-python#3286.

🤖 Generated with Claude Code

The ChatGPT consumer Codex backend (chatgpt.com/backend-api/codex)
intermittently emits response.completed events with response.output = null
(gpt-5.5, May 2026). openai==2.24.0 lib/_parsing/_responses.py:61
iterates response.output without a None guard, raising
"TypeError: 'NoneType' object is not iterable" mid-stream.

agent/codex_runtime.py already sidesteps the bug structurally by
consuming the raw event stream -- but any caller still on the
high-level responses.stream() / responses.parse() helpers
(third-party plugins, future provider profiles, regressions) is exposed.

This adds a small defensive wrapper around parse_response in
agent/_openai_compat.py, installed on `import agent`. It coerces a
None response.output to [] before delegating to the original function.
Becomes a no-op once openai-python ships a guarded release.

Refs: openai/openai-python#3322, NousResearch#3316, NousResearch#3286.

Co-Authored-By: Claude Opus 4.7 <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 labels May 28, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for this — closing as already fixed on main.

The Codex null-output crash (response.completed with output: null from the chatgpt.com backend → TypeError: 'NoneType' object is not iterable → surfaced as "non-retryable HTTP None") is resolved by commits already on main:

  • cb38ce28c — drop the SDK responses.stream() helper and consume events directly, rebuilding output from response.output_item.done events so the null terminal-event output is never iterated (refactor(codex): drop SDK responses.stream() helper; consume events directly #33042).
  • 43a3f119f — recover Codex streams with null output.
  • dc9d677d5 — classify TypeError('NoneType … not iterable') as a retryable provider-shape error so retry/fallback runs instead of killing the turn.

Your fix targets the same path that's now hardened upstream, so there's nothing left to merge here. Your authorship is preserved in your branch; I'm crediting your report in the umbrella issue #33932 (now closed). Appreciate the contribution.

@teknium1 teknium1 closed this Jun 30, 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 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