[Desktop/Sidebar] Large-context sidebar fork repeatedly aborts WebSocket send before HTTP fallback
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Reporter: Codex diagnostic session on behalf of the affected user
Date: 2026-08-30
Severity: Medium
Reproducibility: Often
Summary
In the Windows Codex desktop app, a temporary sidebar/fork chat created from a long-running task repeatedly fails while sending the first Responses WebSocket request. The same turn succeeds only after exhausting five WebSocket retries and falling back to compressed HTTP, while the main task remains responsive over an existing WebSocket.
Expected Behavior
Opening a sidebar/fork chat from an active task and sending a question should produce a response without surfacing a transport error. If the inherited context is too large or cannot be sent incrementally, the client should compact it, use a suitable transport immediately, or recover without showing a terminal WebSocket error.
Actual Behavior
The sidebar/fork turn cannot reuse the main task's WebSocket state, establishes a new WebSocket successfully, and then aborts during the send phase with Windows socket error 10053. Five retries repeat the same pattern. The client then falls back to HTTP; the large request is compressed and eventually returns HTTP 200 several minutes later. The main task continues normally throughout.
Reproduction Steps
Prerequisites:
- Windows Codex desktop app.
- A long-running local task with substantial accumulated conversation/tool context.
- Responses transport using
wss://chatgpt.com/backend-api/codex/responses. - Observed environment used an explicit local HTTP proxy at
127.0.0.1:7890; whether a proxy is required to reproduce is unknown.
- Open or continue a long-running local Codex task with extensive prior tool calls and context.
- Open the temporary sidebar chat/fork attached to that task.
- Send a normal text question from the sidebar.
- Observe that the main task remains responsive.
- Observe the sidebar turn retry its WebSocket request and eventually surface the error shown below.
- Inspect diagnostic logs and observe successful WebSocket handshakes followed by send failures, five retries, and an HTTP fallback.
Minimal Reproduction
The smallest confirmed reproduction is an ephemeral thread/fork from a large active task. In the observed occurrence:
- Main task context during the same interval: approximately 163k–189k tokens.
- Sidebar/fork turn usage/context scope: 595,011 tokens.
- The sidebar/fork was not automatically compacted because its logged compaction threshold was 784,800 tokens and its full context limit was 828,400 tokens.
The exact minimum context size that triggers the failure has not been established.
Environment
Toolkit & Agent
| Detail | Value |
|---|---|
| Agent / Client | OpenAI Codex desktop app |
| Desktop App Version | 26.825.3734.0 |
| Bundled Codex Version | codex-cli 0.150.0-alpha.12.2 |
| Model / Reasoning | gpt-5.6-sol / ultra |
| Agent Workspace Root | <REDACTED local workspace> |
| Available MCP Tools | N/A to reproduction; failure occurs during model transport before tool invocation. Diagnostics used local shell and read-only SQLite inspection. |
Platform
| Detail | Value |
|---|---|
| OS | Microsoft Windows 11 Education, 10.0.22000 (Build 22000) |
| Architecture | x64 |
| Local Proxy | Clash Verge 2.5.2 / Mihomo mixed HTTP port 127.0.0.1:7890 |
| Proxy Selection | One fixed outbound selection was active; hostname and credentials omitted |
Error Output
stream disconnected before completion: failed to send websocket request: IO error: 你的主机中的软件中止了一个已建立的连接。 (os error 10053)
Sanitized operational timeline from the affected turn:
21:14:39 incremental request failed, websocket reuse properties didn't match
21:14:54 stream disconnected - retrying sampling request (1/5) ... os error 10053
21:14:56 successfully connected to websocket
21:15:19 stream disconnected - retrying sampling request (2/5) ... os error 10053
21:15:21 successfully connected to websocket
21:15:56 stream disconnected - retrying sampling request (3/5) ... os error 10053
21:15:58 successfully connected to websocket
21:16:34 stream disconnected - retrying sampling request (4/5) ... os error 10053
21:16:38 successfully connected to websocket
21:17:16 stream disconnected - retrying sampling request (5/5) ... os error 10053
21:17:20 successfully connected to websocket
21:17:56 falling back to HTTP
21:17:58 pre_compression_bytes=48642221 post_compression_bytes=28473971 compression_duration_ms=2101
21:22:14 responses_http returned HTTP 200
21:23:05 total_usage_tokens=595011 auto_compact_scope_tokens=595011 full_context_window_limit_reached=false token_limit_reached=false
Every retry completed TCP/proxy/TLS/WebSocket Upgrade successfully. Each new WebSocket then failed in the send phase roughly 20–38 seconds later.
Visual Evidence
N/A — the exact UI error text and sanitized transport timeline are included above. No screenshot is attached to avoid exposing project information.
Impact
- Scope: Observed in temporary sidebar/fork chats attached to very large, tool-heavy tasks on Windows.
- User impact: Sidebar chat becomes unreliable and may display a terminal transport error even though the main task remains healthy.
- Delay: HTTP fallback took several minutes in the observed turn.
- Workaround: Start a new focused task with a short handoff summary, or wait for the automatic HTTP fallback. Restarting the app may clear stale connections but does not reduce inherited context size.
- Blocking: Does not block the main task, but prevents reliable use of the sidebar for context-aware questions on long-running tasks.
Related Files
| File | Relevance |
|---|---|
%USERPROFILE%\\.codex\\logs_2.sqlite |
Contains the structured transport, retry, fallback, request-size, and token-scope events summarized above. Not attached because it can contain sensitive session metadata. |
%USERPROFILE%\\.codex\\sessions |
Contains session transcripts. Not attached or quoted beyond sanitized operational metadata. |
Notes
- Observation: The affected sidebar/fork turn and healthy main task used the same
codex.exeprocess, model, endpoint, and explicit local proxy route. - Observation: The main task reused an active WebSocket and had no network retry during the comparison window. The ephemeral fork logged
websocket reuse properties didn't match, created new WebSockets, and exhausted all retries. - Observation: The HTTP fallback accepted the same logical request after zstd compression and returned 200.
- Hypothesis (unconfirmed): The failure may be related to sending a very large initial Responses payload over a fresh WebSocket, such as a client/proxy/upstream buffering, flow-control, frame-size, or write-timeout boundary. Additional instrumentation is required to localize which component closes the connection.
- Hypothesis (unconfirmed): A lower compaction threshold or preserving incremental response-chain state for sidebar forks might avoid the large initial request, but no fix is prescribed by this report.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by inspecting the sanitized transport, retry, fallback, request-size, and token-scope events in %USERPROFILE%.codex\logs_2.sqlite, then compare the affected fork with the healthy main task and consult session transcripts under %USERPROFILE%.codex\sessions. Determine which component closes the fresh WebSocket during the send phase and verify that large sidebar/fork turns no longer repeatedly fail before fallback or surface a terminal transport error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop-dev, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100