Remote Control: app messages sync into the session input but never submit (fleet-wide silent message loss); RC never recovers after compaction

Open 💬 1 comment Opened Jul 7, 2026 by mennovdmm

Summary

When controlling local Claude Code sessions from the mobile app via Remote Control, user messages typed in the app frequently never reach the session: the text syncs into the session's input field (visible in the local TUI) but the submit is never delivered — while the RC transport reports healthy. In one working day we logged 11 stranded user messages across 10+ concurrent sessions.

Environment

  • Claude Code 2.1.198 (native build, macOS/arm64, darwin 25.5.0)
  • Long-running sessions in tmux on an always-on Mac ("agent fleet"), each connected via /remote-control
  • Controlled from the Claude iOS app
  • Auth: claude.ai subscription OAuth

Observed failure modes (all reproduced, with --debug-file evidence)

1. Submit loss while transport is healthy. A message typed in the app appears as text in the session's input field (❯ <text>) but never submits. The debug log at the same time shows a healthy transport: hourly SSETransport: Connected re-establishments and CCRClient: Heartbeat sent minutes before/after — no disconnect, no error. The user sees a "frozen chat"; locally the session is idle with queued text.

2. Unsent app drafts re-sync repeatedly. Text left in the app's compose box (never sent) keeps re-appearing in the session's input field after being cleared locally (Escape). Only clearing the compose box in the app stops it. Combined with (1) this makes it impossible to tell a stranded message from a draft.

3. Choice dialogs (AskUserQuestion / numbered menus) cannot be driven from the app. When a session shows a native select menu ("Enter to select · ↑/↓ to navigate"), answers typed in the app land as text in front of the menu and strand. The user's answer ("1. <option>") is never applied; locally pressing the option number works fine.

4. Queued input during a busy turn sometimes never auto-submits. Input delivered while the session is mid-turn (spinner active) is queued in the input field as expected, but after the turn completes it sometimes stays in the field indefinitely instead of auto-submitting. Notably, a bare Enter on such stranded text does NOT submit it — only clearing the field and re-typing the text fresh works.

5. RC dies over compaction and never recovers. During/after /compact on busy sessions the SSE stream misses liveness and burns through its retry budget: [SessionsV2Client] Liveness timeout, reconnecting[SessionsV2Client] Reconnect budget exhaustedRemote Control disconnected. The session keeps running locally, but the app never reconnects and offers no signal that the link is dead — the session's footer still shows /rc. Only killing the session and re-resuming with a fresh /remote-control restores app access.

Impact

For anyone running multiple remote-controlled sessions this is severe: instructions silently vanish (the user re-explains work in other chats, trust erodes), and there is no user-visible indicator distinguishing "delivered" from "stranded". We had to build external tmux-scraping watchdogs to detect stranded input and re-deliver it.

Suggested fixes

  • App-side delivery acknowledgment: show a failed/undelivered state in the app when a message doesn't reach the session.
  • Make queued text auto-submit reliably at turn end, or make Enter submit synced text.
  • Let RC reconnect after compaction instead of permanently giving up when the retry budget is exhausted (or surface the dead link in the app + session footer).
  • Make select menus drivable from the app.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗