fix(responses): backfill output[] when missing, not only when empty#602
Closed
williamjameshandley wants to merge 1 commit into
Closed
Conversation
The non-streaming /v1/responses collector (collectPassthrough) backfills
`response.output` from accumulated `response.output_item.done` events
and `response.output_text.delta` chunks when the upstream
`response.completed` event has `output: []`. The guard:
if (Array.isArray(resp.output) && resp.output.length === 0) { ... }
only matches the *empty array* case. Upstream now (observed on
gpt-5.5 via ChatGPT subscription, 2026-05-27) frequently omits the
`output` field entirely from `response.completed`, in which case
`Array.isArray(undefined)` is false and the backfill is skipped.
The final non-stream JSON body returned to the client then contains
no `output` field at all. Clients using the openai SDK's `Response`
object hit `TypeError: 'NoneType' object is not iterable` when the
`output_text` property iterates `self.output`.
Loosen the guard to also fire when `output` is missing:
if (!Array.isArray(resp.output) || resp.output.length === 0) { ... }
The body of the branch is unchanged — it only runs when there's no
upstream output to copy through, so widening the guard is safe.
Verified end-to-end: gpt-5.5 with stream=false now returns
`output: [{...message...}]` and `output_text: "ok"` for a simple
prompt; mcp-handley-lab's openai adapter (which calls
`responses.create(stream=false)`) recovers from
`'NoneType' is not iterable` to normal "ok" reply.
archlinux-github
pushed a commit
to archlinux/aur
that referenced
this pull request
May 27, 2026
Upstream collectPassthrough only backfills response.output[] from stream events when it's an empty array. Upstream now (2026-05-27) often omits the field entirely from response.completed, causing the openai SDK's output_text property to crash with 'NoneType is not iterable'. Patched against the v2.0.76 tarball via prepare(). Upstream PR: icebear0828/codex-proxy#602
|
+1 |
icebear0828
added a commit
that referenced
this pull request
May 27, 2026
The completed.response.output field may be absent entirely (not just an empty array) from upstream. Change the guard from `Array.isArray && length === 0` to `!Array.isArray || length === 0` so both cases trigger backfill from streamed output_item.done / text deltas. Add two tests covering the missing-output path. Addresses #602.
Owner
|
Thanks! The fix and two additional tests covering the missing-output path have been landed on dev (7f6765d). Addresses this PR's change with test coverage. |
icebear0828
added a commit
that referenced
this pull request
May 27, 2026
- CHANGELOG: CORS allowlist, Docker arch detection, OS cert store, output backfill - README/README_EN: add @aeltorio, @williamjameshandley, @FlavienKlr to contributors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The non-streaming
/v1/responsescollector (collectPassthroughinsrc/routes/responses.ts) backfillsresponse.outputfrom accumulated stream events when the upstreamresponse.completedevent omits it. The current guard only matches the empty array case:But upstream (observed on
gpt-5.5via ChatGPT subscription, 2026-05-27) frequently emitsresponse.completedwith theoutputfield missing entirely, not as[].Array.isArray(undefined)returnsfalse, the backfill is skipped, and the final non-stream JSON returned to the client has nooutputfield at all.Symptom
Clients using the official
openaiPython SDK getTypeError: 'NoneType' object is not iterablewhen their code accessesresponse.output_text— the SDK's@propertyiteratesself.outputwithout a None check:Fix
One-line: loosen the guard to also fire when
outputis missing:The body of the branch is unchanged — it only runs when there's no upstream
outputto copy through, so widening the trigger is safe.Verification
End-to-end on lovelace (Arch Linux, codex-proxy 2.0.76 with this patch applied):
Before: response JSON has no
outputfield (33 top-level keys,outputabsent).usage.output_tokens=5but generated text is dropped.After: response JSON contains
mcp-handley-lab's openai adapter (which calls
responses.create(stream=False)) recovers from the'NoneType' is not iterablecrash and returns normal text.Notes