Repository navigation
macOS: chats develop repeated WebSocket Broken pipe failures during media work, despite reinstall #51889
Description
The user observes both failures when the assistant tries to use DaVinci Resolve. This is a suspected trigger; the cause remains unconfirmed.
Update, 2026-10-08 02:09 UTC: The previously successful fresh control chat has now developed the same failure after further project work. This is not limited to the forked conversation. The initial comparison below describes its behavior at 00:37 UTC, not its current behavior.
Follow-up: initially working fresh chat now fails
The original empty chat (confirmed to have no forked_from_id) initially answered a greeting in approximately four seconds. After further use it now logs repeated WebSocket failures, five-attempt retry sequences, and HTTP fallback while still using GPT-6.1 Sol High and the built-in OpenAI provider.
Redacted excerpts from 2026-10-08:
02:05:42Z retrying sampling request (4/5)
sampling_error=stream disconnected before completion: IO error: Broken pipe (os error 32)
02:05:47Z retrying sampling request (5/5)
sampling_error=stream disconnected before completion: websocket closed by server before response.completed
02:06:00Z falling back to HTTP
02:06:00Z Compressed request body with zstd
pre_compression_bytes=22039511 post_compression_bytes=13962368 compression_duration_ms=75
02:07:20Z Compressed request body with zstd
pre_compression_bytes=22040000 post_compression_bytes=13962557 compression_duration_ms=75
02:09:26Z retrying sampling request (1/5)
sampling_error=stream disconnected before completion: IO error: Broken pipe (os error 32)
02:09:28Z retrying sampling request (2/5)
sampling_error=stream disconnected before completion: websocket closed by server before response.completed
Read-only inspection of this fresh chat's complete historical rollout finds 21 typed image occurrences: 20 in tool outputs and one in a user message. Their historical image URLs total approximately 31.4 million characters. This is a whole-rollout count, not the size of the current active context or a count of unique images.
A compaction record at 01:21:55 UTC contains replacement history serializing to approximately 202 KB under the inspection script. Subsequent failing requests around 02:06 UTC were approximately 22 MB before compression. This suggests that growth after a compaction deserves investigation; it does not prove a particular transport-size limit or that compaction fixes all failures.
The current evidence supports reporting a recurring failure during accumulated media work, rather than only a corrupt fork. The exact source of the WebSocket disconnection remains unconfirmed. Thread/turn IDs, raw messages, screenshots, and local paths remain omitted.
Additional potentially related reports suggested by the issue bot: #51136 and #51580.
Initial report and comparison (00:37 UTC)
What version of the Codex App are you using?
ChatGPT desktop app 26.1002.52244, build 13536, bundle ID com.openai.codex.
The issue persisted after replacing the previous 26.930.61225 app with the official signed and notarized installer and relaunching it. User data was retained.
What subscription do you have?
Not collected for this report. Authentication is ChatGPT sign-in, using the built-in OpenAI provider.
What platform is your computer?
macOS 27.0.1, Apple Silicon arm64.
What issue are you seeing?
One affected conversation repeatedly displays Reconnecting 5/5, the error below, and Thinking, even after short greetings such as hi and ok. Replies in this conversation are extremely delayed.
stream disconnected before completion: IO error: Broken pipe (os error 32)
A separate fresh chat in the same project and app, using GPT-6.1 Sol High, answers hi normally. Local metadata confirms that both tested conversations use gpt-6.1-sol, high, and the built-in openai provider.
An important distinction: the affected chat was created on the test day, but its session metadata contains a forked_from_id pointing to the earlier failing conversation. The working fresh chat has no forked_from_id. A recently created fork therefore does not provide the same clean control as an empty new chat.
What steps can reproduce the bug?
Observed sequence with the existing affected state (a standalone deterministic reproducer has not been established):
- Continue a long video/rendering conversation that has already become slow and started reconnecting.
- Create a fork of that conversation and send a short greeting.
- Observe repeated broken-pipe retries in the fork.
- Reinstall/relaunch the official desktop app, retaining user data, and send another short message in the fork.
- The fork again retries through
5/5and falls back to HTTP. - Create a separate empty chat in the same project, select GPT-6.1 Sol High, and send
hi. It returns a greeting normally.
At 2026-10-08 00:37 UTC, the affected turn was accepted around 00:37:21, logged broken-pipe retries through 00:37:40, and fell back to HTTP at 00:37:47. The fresh control turn was accepted around 00:37:48 and produced its assistant message around 00:37:52.
What is the expected behavior?
A fork should remain usable for short follow-ups. If retained history cannot be transported reliably, the app should offer an actionable recovery path and clearly distinguish retrying from actual model thinking.
Additional information
Read-only inspection of the affected thread's client logs found:
2026-10-08T00:32:37Z stream disconnected - retrying sampling request (5/5) ...
sampling_error=stream disconnected before completion: IO error: Broken pipe (os error 32)
2026-10-08T00:32:43Z falling back to HTTP
2026-10-08T00:32:44Z Compressed request body with zstd
pre_compression_bytes=36961231 post_compression_bytes=25093868 compression_duration_ms=112
2026-10-08T00:37:40Z stream disconnected - retrying sampling request (5/5) ...
sampling_error=stream disconnected before completion: IO error: Broken pipe (os error 32)
2026-10-08T00:37:47Z falling back to HTTP
2026-10-08T00:37:47Z Compressed request body with zstd
pre_compression_bytes=36977935 post_compression_bytes=25094188 compression_duration_ms=110
The failing path logs transport="responses_websocket" and connects to wss://chatgpt.com/backend-api/codex/responses before HTTP fallback. These are client-recorded request-body sizes, not billing totals or measured bytes successfully transferred.
The affected fork was originally created with client metadata 0.160.1; the fresh control created after reinstall reports 0.162.0-alpha.2. Both use paginated history. A VPN client was running during diagnosis; no controlled route-change comparison was performed.
Related reports: #20805 (image-heavy desktop chats reconnect), #43015 (large history requests and stalls), and #19821 (retry budget before HTTP fallback). This report adds a newly created fork versus empty-chat control, a current macOS app reinstall, and measured request sizes under the same model/effort setting.
Request size or inherited history may be a contributor, but this evidence does not establish the exact cause of the disconnect or a universal size limit. Raw screenshots, full conversations, credentials, account identifiers, local paths, and thread IDs are omitted from this public report.
Activity
github-actions commentedon Oct 8, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
[-]macOS: forked chat retries Broken pipe even for greetings; fresh same-project Sol High chat works[/-][+]macOS: chats develop repeated WebSocket Broken pipe failures during media work, despite reinstall[/+]andrijaradiv commentedon Oct 9, 2026
I'm also hitting this on macOS after updating to desktop version 26.1002.52244 (build 13536), with bundled CLI 0.162.0-alpha.2. It repeatedly interrupts work, and moving to a new chat hasn't prevented it from recurring as context grows.
Additional measured failures
On 2026-10-08 (UTC), local diagnostics recorded:
error sending request; request size 37,054,461 bytes uncompressed, approximately 26,831,150 bytes compressed.error sending request; request size 27,083,946 bytes uncompressed, approximately 19,484,393 bytes compressed. This task was created that day.Earlier diagnostics on October 6 recorded
received fatal alert: BadRecordMac,Broken pipe (os error 32), and WebSocket closure beforeresponse.completed.Remote compaction also fails with
error sending request, leaving the affected chat unable to complete the proposed cleanup. These are observations across attempts; they don't establish a single root cause.What has and hasn't been ruled out
Small fresh requests and basic DNS/TLS probes succeed, but they don't reproduce the failing large-history workload. No active system proxy or connected VPN was observed during the checks. A controlled alternate-network comparison hasn't been completed.
Accumulated screenshot/image payload is a hypothesis consistent with this issue and #24550, not a locally proven cause or a confirmed request-size limit. I haven't edited transcripts or installed third-party scrubbers or proxies.
Could maintainers investigate recovery when a large history can't successfully compact, and provide a supported way to reduce retained image payload without discarding project context or manually editing session data? A fresh chat is only a temporary workaround here.
Raw logs, private project content, local paths, account details, and screenshots are omitted from this public report.
l7450000-spec commentedon Oct 9, 2026
@andrijaradiv We observed a similar pattern on desktop 26.1002.52244 / bundled CLI 0.162.0-alpha.2. We documented our measurements in #52456. Sharing what temporarily recovered two of our affected threads, with an important qualification: this was an unsupported local history-recovery experiment, not an official fix, and it does not establish the cause of your TLS/BadRecordMac errors.
Our approach was to externalize historical inline images rather than ask the already-failing thread to perform remote compaction:
input_imagepayloads in the latestcompacted.payload.replacement_historyplus subsequent response items, separately from the entire persisted rollout. Whole-file size and token counts are not equivalent to the active image/request payload.durable rollout shrank before projection. Our implementation preserved every record's original byte length and offset with trailing JSON whitespace, validated the result, checked that the source had not changed, then replaced the file atomically. The physical file therefore stayed large, but the parsed inline image payload was removed. We did not rebuild SQLite indexes. This is version/storage-specific: your report mentions paginated history, so our JSONL procedure must not be assumed to apply unchanged to your installation.In our two measured cases, estimated active image payloads were approximately 40.1 MB (32 images) and 46.9 MB (48 images) before recovery. The minimal tests then completed in 10.9 seconds and 20.4 seconds, with no recorded warnings/errors in their respective validation windows. These demonstrate minimal response recovery, not a durable fix or full-workload validation.
The tradeoff is that old image pixels are no longer automatically present in the model context; they must be reopened from the saved files when needed. New image reads accumulate again. In one recovered thread, a new screenshot plus ten tool-read Word page previews added 15.6 MB of encoded image content and reconnects returned. A hash comparison confirmed the repaired prefix was unchanged: the images were new additions, not leftover data or a reverted cleanup. This is not evidence of a universal 15 MB limit. We have also seen a separate TLS-handshake interruption in a thread with less than 1 MB of image data that subsequently continued working, so not all reconnects fit the large-history hypothesis.
If you prefer not to edit transcripts, this is primarily diagnostic evidence for maintainers, not a supported workaround you can apply from the UI. We agree that Codex needs a supported, backed-up per-thread recovery option and bounded image retention that preserve project context without requiring users to manipulate session storage. No raw conversations, private images, local paths, or credentials are included here.