Codex Desktop SSH: image on first turn closes app-server before turn/start

Open 💬 1 comment Opened Aug 4, 2026 by f0rr0
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From "About Codex" dialog)?

Codex Desktop 26.727.51351 (build 6119), bundled codex-cli 0.146.0-alpha.9.2.

The SSH remote is currently on stable codex-cli 0.146.0. I also installed the exact bundled Linux build, 0.146.0-alpha.9.2, restarted both the remote app-server and proxy, and reproduced the same failure before restoring stable 0.146.0.

What subscription do you have?

Not specified; the failure occurs in the local Desktop-to-remote app-server transport before model processing.

What platform is your computer?

Client:

  • macOS 26.5.1 (25F80)
  • Apple Silicon (arm64)

SSH remote:

  • Ubuntu 24.04.4 LTS
  • x86_64
  • Connected through an ordinary OpenSSH host alias over Tailscale 1.98.4

No hostnames, IP addresses, or private project paths are included below.

What issue are you seeing?

Creating a new Codex Desktop task in an SSH remote project with an image attachment consistently disconnects the remote app-server before the first turn/start reaches it. Text-only messages and text-only new tasks work normally.

The Desktop UI reports:

Codex app-server is not available

The exact event sequence from the production Desktop log is:

06:55:26.155 thread/start succeeded (578 ms)
06:55:26.904 app_server_connection.closed code=1006
06:55:26.955 turn/start failed: remote_unavailable / Codex app-server is not available
06:55:26.984 Background first turn failed

The new thread is allocated an ID, but no rollout is created because its first turn never starts. The connection automatically reinitializes approximately four seconds later, and text traffic works again.

The SSH proxy reports the same transport signature documented in other remote attachment failures:

Error: failed to relay data between stdio and socket

Caused by:
    0: failed to copy data from stdin to socket
    1: Broken pipe (os error 32)

The SSH session itself is healthy. During the failed connection, OpenSSH reported approximately 962 KB of raw outgoing channel data before the socket closed. This is not enough to determine the WebSocket message's announced full length: an acceptor can reject a frame from its header before the complete body is relayed. The current production Desktop log does not record the serialized turn/start frame size.

Controlled transport checks

I tested the same path independently:

WebSocket client -> SSH stdio -> codex app-server proxy -> remote Unix control socket

Inline image turn/start requests of 1,000,200 bytes and 6,715,596 bytes were both parsed successfully by the stock remote app-server. Each returned the expected application-level thread not found response for a deliberately fake thread ID instead of disconnecting the transport.

I also verified:

  • The remote app-server process remains alive when Desktop's individual connection drops.
  • Remote CPU, RAM, disk, SSH, and Tailscale health are normal.
  • The failure reproduces with both stable 0.146.0 and exact Desktop-version parity (0.146.0-alpha.9.2) on the remote.
  • The Mac Desktop app is the newest release in the production update feed.
  • The v2 protocol supports inline data:image/...;base64,... inputs, and Desktop intentionally uses inline images for SSH remotes.

This isolates the failure to Desktop's remote first-turn attachment path or the app-server WebSocket boundary, rather than authentication, host reachability, or CLI version skew.

What steps can reproduce the bug?

  1. Add a Linux SSH remote to Codex Desktop on macOS.
  2. Open a project on that remote.
  3. Create a new task.
  4. Enter a prompt and attach an image in the first message.
  5. Submit it.
  6. Observe Codex app-server is not available and a brief remote reconnect.
  7. Create another new task with text only; it succeeds.

What is the expected behavior?

The image should be delivered to the remote task without closing the app-server connection. If the attachment exceeds a protocol limit, Desktop should either materialize it on the SSH host and send a localImage path, resize it, or reject it before starting the thread with a clear size error. It should not create an empty thread, drop the transport, and surface a generic availability error.

Desktop should also log the serialized frame size and preserve the underlying WebSocket close reason so this path is diagnosable.

Related issues

  • #36518 reports the same 1006 / broken-pipe signature for SSH image attachments whose serialized request exceeds the 16 MiB WebSocket limit. This report may be another reproduction of that boundary, but the production app does not expose the failed frame's announced length, and the failure occurs specifically while creating the first turn of a new remote task.
  • #32512 covers the same 16 MiB WebSocket boundary when transferring a large rollout during cross-host handoff.
  • #23919 covers remote SSH reconnect and recovery instability after app-server transport drops.
  • #33210 covers an image-only first turn that never reaches sampling after prewarm timeout; its lifecycle differs, but both failures occur before the first image turn becomes usable.

Current workaround

Upload the image separately with scp and reference its remote filesystem path in the prompt. This avoids Desktop's inline image attachment transport.

View original on GitHub ↗

1 Comment

github-actions[bot] contributor · 24 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #36518

Powered by Codex Action