Skip to content

[Bug]: Long Codex thread fails only through OpenCodex proxy (WS 1006 / response prelude timeout); bypass works immediately #4191

Description

@mehmeemow

Client or integration

Codex App (also reproduced from Codex CLI when resuming the same problematic thread).

Area

Streaming

Summary

A long-running Codex conversation became effectively unusable only while traffic was routed through OpenCodex. The same account, model, machine, repository and thread work normally again as soon as the OpenCodex proxy is disabled/bypassed.

This does not look like a generic network outage because the failure is both thread-specific and proxy-path-specific.

With OpenCodex enabled, the problematic parent thread repeatedly failed with either:

stream disconnected before completion:
Upstream stream terminated unexpectedly:
codex websocket closed before a Responses terminal event
(close 1006 Connection ended)

or:

stream disconnected before completion:
Upstream stream terminated unexpectedly:
codex websocket response prelude timed out

After OpenCodex was disabled/bypassed, the same existing thread resumed and worked normally immediately, without fork, rollback, or compaction recovery.

Expected behavior: OpenCodex should transparently proxy the same Codex Responses request, or safely fall back to HTTP/SSE when the upstream WebSocket path cannot complete.

This appears related to one or more WebSocket relay edge cases such as large replay payloads, loss of upstream close code/reason, the response-prelude timeout, or lack of safe HTTP/SSE fallback after an already-open WebSocket terminates.

Related issues:

This report adds a real-world A/B observation: the exact same previously failing thread becomes healthy immediately when OpenCodex is bypassed.

Reproduction

  1. Run Codex Desktop on Windows with Codex traffic routed through OpenCodex to the normal ChatGPT/Codex upstream.
  2. Open/resume an existing long-running conversation.
  3. Observe repeated stream disconnected before completion failures for many hours.
  4. Switch the host network to a mobile hotspot. Observe the same failure.
  5. On the same machine, start Codex CLI and create a fresh conversation. The fresh conversation replies normally (Hello!).
  6. In Codex CLI, resume the same problematic existing conversation. The failure reproduces.
  7. While the parent conversation is failing, previously spawned sub-agents can continue executing normally.
  8. Observe one or both of the errors shown in the Logs section below.
  9. Disable/bypass OpenCodex without otherwise changing the account, model, repository, machine, or conversation.
  10. Resume the same existing problematic thread again.
  11. The thread now works normally.

A/B matrix:

Test Result
Codex Desktop + OpenCodex + existing long thread ❌ stream disconnected
Same path on mobile hotspot ❌ same failure
Codex CLI + OpenCodex + fresh thread ✅ normal reply
Codex CLI + OpenCodex + same existing long thread ❌ stream disconnected
Sub-agents under the problematic conversation ✅ continued executing
Same existing long thread with OpenCodex bypassed ✅ works normally

Suggested diagnostics for reproducing this in OpenCodex:

  • log serialized first-message/request size in bytes;
  • preserve/log the actual upstream WebSocket close code and reason;
  • log elapsed time from send() to quota/metadata control events and to the first non-control Responses event such as response.created;
  • record whether any downstream Responses bytes/events were emitted before failure;
  • record whether the exchange was eligible for a safe HTTP/SSE fallback.

Potential mitigations:

  1. Preserve and expose the real upstream WS close code/reason instead of collapsing it into a generic downstream 1006-style failure.
  2. Preflight large initial WS payloads and route to HTTP/SSE before opening WS when near the upstream size limit.
  3. If WS opens but closes/times out before any real Responses event is delivered downstream, use HTTP/SSE fallback where it is safe and cannot duplicate inference.
  4. Revisit or make configurable the response-prelude deadline for large/slow requests.

Version

OpenCodex v2.49.0

Codex Desktop 26.903.61454

Operating system

Windows 11

Provider and model

Canonical ChatGPT/Codex authenticated upstream. Exact model identifier was not captured as part of the initial incident.

Logs or error output

stream disconnected before completion:
Upstream stream terminated unexpectedly:
codex websocket closed before a Responses terminal event
(close 1006 Connection ended)

and later:

stream disconnected before completion:
Upstream stream terminated unexpectedly:
codex websocket response prelude timed out

Screenshots and supporting files

No private conversation content, repository content, credentials, or account identifiers are attached.

The strongest supporting evidence is the A/B result: the same existing long thread fails through OpenCodex and immediately succeeds when OpenCodex is bypassed.

Redacted configuration

{
  "client": "Codex Desktop / Codex CLI",
  "proxy_path": "Codex -> local OpenCodex -> canonical ChatGPT/Codex upstream",
  "control_test": "Codex -> canonical ChatGPT/Codex upstream (OpenCodex bypassed)",
  "result_with_proxy": "stream disconnected",
  "result_without_proxy": "same thread works normally"
}

No tokens, account identifiers, request credentials, private conversation text, or repository contents are included.

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstreamingSSE, WebSocket, terminal stream frames

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions