Remote Control cannot attach to a live CLI session on the workstation (completed threads work, in-progress ones fail)

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

What variant of Codex are you using?

CLI + ChatGPT iOS Remote Control (paired hosts)

What feature / fix would you like?

Support the normal workstation-primary workflow:

  1. Start and run the task in Codex CLI on the workstation
  2. Use the phone only to monitor progress, approve actions, and send short steering replies
  3. Return to the same live CLI session without quit/resume or forking

Today, Remote Control effectively allows the phone to open completed threads, but fails when the workstation CLI already owns a live / in-progress session.

Why this matters

Almost nobody’s main coding surface is the phone. The realistic loop is:

  • keyboard + terminal on the workstation
  • phone as a second screen for status + decisions while away from the desk

Claude Code Remote Control (/rc) matches this model: the local CLI session stays primary; mobile is another window into the same live session.

Codex Remote currently behaves more like: “pair a host → operate threads from mobile,” and does not reliably share an already-attached live CLI session with iOS.

What happens today (observed)

| Session state | iOS Remote result |
|---|---|
| Completed (no active CLI attach) | Opens and reads normally |
| Live / in-progress CLI session | Fails to load |

On the failing live session, iOS shows:

  • 加载消息时出错:Codex 服务器返回了错误。

(“Error loading messages: Codex server returned an error.”)

  • 此任务无法重新连接

(“This task cannot reconnect”)

So the phone can act as a history viewer for finished threads, but cannot attach to the live session the CLI already owns.

Expected behavior

  • Workstation CLI remains the primary client
  • iOS can attach to that same live thread as a secondary client
  • Monitoring, approvals, and short follow-ups work without forcing the user to start the task from mobile
  • Returning to the workstation TUI does not require quitting and resume, and does not create divergent continuations

Actual behavior

  • Completed threads: OK from iOS
  • Live CLI-attached threads: iOS cannot reconnect / server error
  • Practical workaround pushed by the product shape: start work from Remote/App side instead of CLI — awkward for workstation-first developers

Suggested direction

Any of:

  • Explicit multi-client live attach (CLI + mobile on the same thread)
  • Or a clear “monitor/approve-only” secondary session mode for Remote
  • Or document and enforce single-writer rules without hard-failing the phone on live threads (e.g. read-only view + queued approvals)

Related: #32445, #34632, #23011

Additional information

_No response_

View original on GitHub ↗

11 Comments

github-actions[bot] contributor · 17 days ago

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

  • #37403
  • #37450
  • #37947

Powered by Codex Action

seanpianka · 11 days ago

I can reproduce this exact iOS Remote error on macOS, with a more specific discriminator.

  • Remote pairing works and all chats/projects are listed.
  • Working chat: Codex CLI 0.146, historyMode: "legacy".
  • Failing chats: Codex CLI 0.147, historyMode: "paginated".
  • Multiple newer text-only paginated chats fail, so images are not required.
  • Desktop 26.810.52044 build 6662; bundled app-server 0.148.0-alpha.9.
  • Updating/restarting Desktop and reconnecting Remote did not help.
  • Direct local thread/read succeeds for both the working legacy chat and failing paginated chat.
  • The failing paginated response is smaller than the working legacy response, ruling out simple payload-size limits.
  • Failed iOS opens do not reach the host as a thread/read.

iOS displays:

Error loading messages: Codex server returned an error.

This suggests the boundary may be paginated-history handling in the mobile/cloud Remote path, rather than only whether the CLI thread has an active writer.

iOS ChatGPT version: 1.2026.209

I can provide a feedback/session ID and sanitized logs privately.

pps83 · 11 days ago

Crazy this thing isn't implemented; and its partial impl is so flawed: control commands (to view/compact context for example) do not work from mobile

jdcodes1 · 9 days ago

Your completed-vs-live table matches a specific mechanism in the thread store: cross-process writer locks. Every live thread holds an exclusive lock file under $CODEX_HOME/thread-writer-locks/ (https://github.com/openai/codex/blob/1f41cc5d92/codex-rs/thread-store/src/local/writer_lock.rs#L17-L34). The workstation TUI's process owns that lock for the in-progress session; when the Remote Control daemon — a different process — tries to open the same thread for iOS, the acquisition fails and surfaces as the generic "Codex server returned an error." Completed threads hold no writer lock, so they open fine. The same single-writer constraint is what blocks /fork-then-resume in another terminal (#38144, #38297) and produces the empty two-instance replay in #37987.

So "phone as second screen on the live session" needs one of: (1) a read-only attach path that never takes the writer lock — enough for monitoring, and probably the quick win; (2) routing mobile steering/approvals through the process that owns the lock (the app-server multi-client machinery exists; the remote-control daemon would proxy into the owning session rather than opening the thread itself). Option 2 is the Claude-/rc-style behavior you're describing; option 1 could ship first and already covers monitoring.

rodjac-lab · 6 days ago

I can reproduce a closely related paginated-history failure on Android, with the important distinction that live steering still works: the phone can send a new message and receive the reply, but opening the thread is slow and the beginning of the conversation is not rendered.

Environment:

  • Fedora host, standalone codex-cli 0.149.0
  • codex app-server --remote-control --listen unix://, directly supervised by a user systemd service
  • Android 17 / ChatGPT 1.2026.230
  • No Codex/ChatGPT desktop GUI process or desktop client attached to the app-server socket
  • The affected thread was created from Android Remote and has history_mode = paginated

The history is intact and locally readable. I queried the running app-server over its Unix WebSocket:

| Request | Result | Local latency | Encoded response |
|---|---:|---:|---:|
| thread/turns/list, ascending, itemsView: summary | 5 turns, nextCursor: null | 5 ms | 12,714 bytes |
| thread/turns/list, ascending, itemsView: full | the same 5 turns, nextCursor: null | 46 ms | 3,104,863 bytes |
| thread/read, includeTurns: true | the same 5 turns | 56 ms | 3,106,375 bytes |

The returned turn statuses are interrupted, completed, completed, completed, inProgress. The first user messages and assistant replies are present in both the rollout and thread_history_1.sqlite; the projection byte offset is current. There is no host-side read error in the app-server journal.

This produces two user-visible symptoms:

  1. Opening the thread on Android is much slower than before paginated history.
  2. The mobile UI shows the recent live exchange but omits the earlier conversation, even though the app-server returns all five turns and reports no next page.

The large full response can explain some latency, but not why the beginning is absent. The 12 KB summary response contains enough information to enumerate every turn, so this looks consistent with a mobile/cloud Remote paginated-history handling problem rather than lost host data or a writer-lock failure.

This is still reproducible on Android app 1.2026.230, newer than the iOS build reported above. Happy to provide sanitized protocol output if useful.

rodjac-lab · 6 days ago

Confirmed temporary workaround on Fedora:

  • keep the current 0.149 app-server as the single Remote Control host;
  • connect the 0.146 TUI client to it with codex 0.146 --remote unix://;
  • start new threads from that TUI.

A live test against the 0.149 server created a normal user thread with history_mode=legacy, while the server remained connected to Android. The server records cli_version=0.149.0 because it owns the thread, but the history contract is legacy.

This matches the tagged source: the 0.149 TUI explicitly sends ThreadHistoryMode::Paginated for non-ephemeral new threads, while 0.146 leaves history_mode unset and the app-server default remains legacy.

This does not convert existing paginated threads, but it provides a workable CLI-first path for newly created threads while retaining the current Remote server and its mobile connection.

jcorreia · 5 days ago

This happens also to me with android, macbook and cmux.

erhanuenlue · 5 days ago

Same issue, on my macbook iTerm session and iphone app.

Anlittledy · 1 day ago

I reproduced the same issue with VS Code + iPhone Remote Control: an active thread owned by VS Code cannot currently be opened on the iPhone, even for viewing. I added OS-level writer-lock evidence and a proposed read-only observer + “Take over here” handoff flow in #40157.

pstayets · 1 day ago

A workaround shaped differently. If you start the task as shell codex, the live PTY is exactly what the phone gets, there is no separate attach step or writer lock to fight, the browser link and the workstation terminal are the same session. Disclosure, I work on Pilot Protocol, which develops shell.online. The limitation, it only helps for sessions launched through it, it cannot adopt an already-running bare codex.

rodjac-lab · 23 hours ago

Status check after the 0.150.0 / 0.150.1 releases:

  • This issue remains open and unassigned, with no maintainer response yet.
  • The official changelog for ChatGPT on iOS 1.2026.230 says long-thread loading was improved and older history is now fetched as needed.
  • The published 0.150.0 / 0.150.1 CLI notes do not mention Android long-thread hydration, read-only Remote attach, writer-lock handoff, or stale-lock lifecycle. The listed 0.150.1 fix concerns retained-image budgeting during Remote compaction.
  • Android users continue to report unusable long-running tasks in #38023.
  • #40157 now proposes read-only observer mode plus an explicit Take over here ownership handoff for threads already owned by another client.

Could a maintainer clarify:

  1. Is the incremental long-thread loading change planned or already rolling out on Android?
  2. Is the observer / writer-handoff design from #40157 under consideration for Remote?
  3. Does 0.150.x include any relevant unlisted fix, or should affected users continue using legacy-history workarounds?