Files
OmniRoute/changelog.d/fixes/codex-nonstream-body-double-read.md
Diego Rodrigues de Sa e Souza a06ddb38e6 fix(codex): non-stream chat 502 'Response body is already used' (single-reader peek) (#7526)
Every non-streaming Codex chat request for a ChatGPT-account connection failed
instantly with [502]: Response body is already used (reset after 1m). The
streaming/playground path was unaffected.

Root cause: peekCodexSseTransientError (open-sse/executors/codex.ts) peeked the
SSE prefix with response.body.getReader(), then called reader.releaseLock() and
response.body.getReader() a SECOND time on the same already-disturbed body to
build the replacement stream. Re-acquiring a reader on a disturbed body throws
on undici ('Response body is already used'); chatCore's generic upstream-error
handling then stamped the TypeError with a default 60s cooldown, masking a pure
code defect as a rate limit (and tripping the codex circuit breaker).

Fix: keep the single reader already held; never touch response.body again.

TDD: a getReader spy that throws on the 2nd acquire reproduces the exact hazard
— 1 test RED against the release code, 2/2 GREEN with the fix; the replacement
body stays byte-identical to the upstream SSE. No regression across the codex
unit suite. Reproduced live on the VPS 2026-07-16.
2026-07-17 02:39:21 -03:00

493 B

  • Fixed every non-streaming Codex (ChatGPT-account) chat request failing with [502]: Response body is already used (reset after 1m): peekCodexSseTransientError re-acquired a reader on the upstream response.body after releaseLock() to continue draining it, which throws on undici. It now keeps the single reader it already holds. The thrown TypeError was also being mis-classified as a 60s rate limit (cooldown + circuit breaker) — that misfire disappears with the double-read fixed.