Remote Control: app messages sync into the session input but never submit (fleet-wide silent message loss); RC never recovers after compaction
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 exhausted → Remote 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.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗