claude-code - 💡(How to fix) Fix iOS Remote Control: mobile UI stuck on pulsing thinking-icon after `/compact`; stale tool indicators remain; no recovery via app reload [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#57891Fetched 2026-05-11 03:22:42
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Author
Timeline (top)
labeled ×5commented ×2

Two distinct Remote Control reliability failures within ~12 hours on the same claude session and same iOS device. They are different failure modes that share a family (Remote Control state-sync gaps), and the second one occurred after the first was fully recovered.

Error Message

  • v2.1.133: "Fixed pressing Esc during conversation compaction showing a spurious 'Error compacting conversation' notification" — touches the /compact flow, but at the UI-error layer, not the Remote-Control-stream layer.
  • Cost of recovery here was lower than the morning bug — just /remote-control again, no process restart needed. But during the 4.5-hour silent window, the mobile UX was indistinguishable from "Claude is just slow today" — no error, no auto-recovery prompt. A casual user would assume the assistant had hung and not realize it was a connectivity issue.
  1. iOS-side error surfacing when the WebSocket transport closes with a 4xxx app-level code — at minimum a non-modal banner ("Connection lost. Tap to reconnect.") rather than a silent pulsing icon.

Root Cause

  • #40388 — Remote Control mobile stuck on "sending" after /clear. Same class (slash-command-induced state mismatch between server and mobile client); closed as duplicate without a master link. The post-/clear and post-/compact cases may share root cause.
  • #28926 — Remote control infinite loading loop on mobile client (closed stale).
  • #52796 — Remote Control session unresponsive after first command from mobile app (open).
  • #34255 — Silent connection drops, no auto-reconnect (open).
  • #28571 — Fails to resync after connection drop (open).
  • #20696 — Compaction deadlocks chats on claude.ai web/mobile (different surface — claude.ai chat, not Code Remote Control — but pairs the same trigger word with the same UI symptom).

Fix Action

Fix / Workaround

Later the same day, ~3.5 hours after the primary-incident workaround had successfully recovered, the same session experienced a Transport closed (code 4092) event on the Remote Control WebSocket with no auto-reconnect, no notification on either side, and no recovery for 4.5 hours until the user manually re-ran /remote-control. This second incident occurred on v2.1.138 — the version that auto-updated during the primary-incident workaround. So v2.1.138 is not a fix for the broader Remote Control reliability story; it definitely still has at least the transport-disconnect-with-no-reconnect failure mode.

This is direct visual evidence of the "stale pairings accumulate in the iOS list" problem described in the Secondary Incident section. A user looking at this list has to guess which entry is live; in this case the visual cue (Connected vs Disconnected) is present, but the duplicate-name shouldn't have to be resolved by the user at all — the dead pairing should be auto-pruned or de-prioritized.

Workarounds tried — UNSUCCESSFUL

RAW_BUFFERClick to expand / collapse

Summary

Two distinct Remote Control reliability failures within ~12 hours on the same claude session and same iOS device. They are different failure modes that share a family (Remote Control state-sync gaps), and the second one occurred after the first was fully recovered.

Primary incident — post-/compact UI freeze (Claude Code v2.1.126)

After running /compact in a long-lived claude session on macOS, the iOS Claude Code app (Remote Control mode) stops rendering new assistant output. The pulsing "Claude is thinking" icon persists indefinitely at the bottom of the screen, and tool-use indicators from BEFORE the compact remain visible (stale). The session on macOS is healthy — text is being produced and processed normally — but it never reaches the mobile UI.

Suspected: race condition between /compact finalizing the prior stream and the mobile client transitioning to receive the post-compact stream.

Secondary incident — silent transport disconnect with no auto-reconnect (Claude Code v2.1.138 — current latest)

Later the same day, ~3.5 hours after the primary-incident workaround had successfully recovered, the same session experienced a Transport closed (code 4092) event on the Remote Control WebSocket with no auto-reconnect, no notification on either side, and no recovery for 4.5 hours until the user manually re-ran /remote-control. This second incident occurred on v2.1.138 — the version that auto-updated during the primary-incident workaround. So v2.1.138 is not a fix for the broader Remote Control reliability story; it definitely still has at least the transport-disconnect-with-no-reconnect failure mode.

Details for both incidents are below.

Environment

  • Claude Code (host): v2.1.126 when the bug occurred (verified from the terminal window's session-start banner; the session was started ~5–6 days before the bug — around Mon 2026-05-04 — and was kept open without restart). After killing the process and restarting, it auto-updated to v2.1.138 where the post-restart pairing worked normally. 8 intermediate releases between bug-version and post-restart-version.
  • Mobile: iOS Claude Code app, Remote Control mode (most recent App Store version as of 2026-05-09)
  • Host OS: macOS (Darwin 25.4.0), claude CLI session
  • Session age: long-lived (~5+ days of conversation including extensive prior tool use)
  • Trigger: /compact slash command

Release notes review (v2.1.126 → v2.1.138)

Most plausible candidate fix in the window: v2.1.133 (release):

Fixed Remote Control stop/interrupt from claude.ai not fully canceling the CLI session the same way local Esc does, causing queued messages to never advance after interrupting a stuck tool or prompt.

Same shape as the bug here: Remote Control state mismatch at a control-flow boundary, with queued messages stuck. The trigger differs (/compact finalization vs. interrupt cancellation), but the failure mode (mobile UI never advancing despite server progress) is shared. Plausible that the v2.1.133 fix also addresses (or is at least adjacent to) the /compact race we saw.

Adjacent / near-miss fixes also worth noting:

  • v2.1.128: "Fixed stale 'remote-control is active' status lines from prior sessions appearing after --resume/--continue" — state-leakage across a session-boundary; same family but different surface.
  • v2.1.133: "Fixed pressing Esc during conversation compaction showing a spurious 'Error compacting conversation' notification" — touches the /compact flow, but at the UI-error layer, not the Remote-Control-stream layer.
  • v2.1.138: "Internal fixes" (no specifics).
  • v2.1.137, v2.1.131, v2.1.136, v2.1.129, v2.1.132: no Remote-Control or /compact-related fixes listed.

If maintainers can confirm whether the v2.1.133 fix already covers the post-/compact race, that may close this issue immediately. If not (i.e., the fix was scoped strictly to interrupt-class transitions, not slash-command-induced ones), the post-/compact boundary still needs its own fix and this report stays valid.

Repro

  1. Run a long session in claude on macOS with extensive prior tool use (Bash, Read, Write, Edit calls).
  2. Pair the session to the iOS app via /remote-control.
  3. Send a few prompts from mobile to confirm round-trip works.
  4. Run /compact.
  5. Observe: mobile UI freezes. Pulsing icon at bottom. Last tool indicator (in my case a "Write" call from before compact) remains shown.
  6. Send a fresh prompt from mobile. The prompt is received by the macOS session and gets a response there, but the response never renders on mobile.

Expected vs actual

Expected: Mobile UI clears the pre-compact tool indicators after /compact completes and renders the new (post-compact) assistant stream as it arrives.

Actual: Mobile UI is frozen on the pre-compact state. Pulsing icon implies the client thinks a stream is still in progress (the pre-compact one).

Screenshots

Primary — post-/compact UI freeze

(See attached 2026-05-09_primary-post-compact-freeze-FIXED.png.)

<img width="400" height="866" alt="Image" src="https://github.com/user-attachments/assets/5720a458-f696-4745-9764-18355db0db61" />

Notes:

  • "Writing today's now." text + Write tool indicator at the very top — that Write call was from BEFORE the /compact, NOT from the current turn. It should have been cleared.
  • The pulsing icon is visible at the bottom.
  • A user prompt ("Hey is this remote session messed up?...") was sent AFTER the compact and is shown in the bubble, but no response from Claude is rendered, despite the macOS session having produced one.

Secondary — stale disconnected pairing accumulation

(See attached 2026-05-10_ios-rc-stale-pairing-cropped-FIXED.png — cropped from a longer iOS app session list.)

<img width="400" height="392" alt="Image" src="https://github.com/user-attachments/assets/dc6836bd-bc24-47b9-9927-f1dd37be311a" />

Taken the morning of 2026-05-10, showing the iOS app's "Code" session list. Two entries with the same session name (calendar-n-task-mgmt):

  • "Today" bucket: Connected (the fresh pairing created at 20:26 PT 2026-05-09, currently live).
  • "Yesterday" bucket: Disconnected (the pairing that died at 16:00 PT 2026-05-09 with WS app-close-code 4092, never cleaned up).

This is direct visual evidence of the "stale pairings accumulate in the iOS list" problem described in the Secondary Incident section. A user looking at this list has to guess which entry is live; in this case the visual cue (Connected vs Disconnected) is present, but the duplicate-name shouldn't have to be resolved by the user at all — the dead pairing should be auto-pruned or de-prioritized.

Workarounds tried — UNSUCCESSFUL

  • Background → foreground the iOS app
  • Pull-to-refresh in the message list
  • The in-app (three-dot) menu options
  • Force-quit and reopen the iOS app
  • /remote-control disconnect + reconnect from the SAME claude process (cycle does not resync)

Workaround that WORKS (confirmed 2026-05-09)

Killing the macOS claude process, restarting (via claude --resume <session> or claude --continue to keep the same session), and running /remote-control to create a new pairing recovers a working mobile UI. The remote-control session disappears from the iOS app, then reappears in a working state on the new pairing.

This implies the bug is in the per-pairing state held by the server (or by the mobile client keyed off the pairing) rather than something the mobile client can self-recover from. A fresh pairing forces both ends into a clean state.

Cost of the workaround

Smaller than it first looks, but non-zero:

  • Preserved: the full conversation transcript on disk (~/.claude/projects/.../<session-id>.jsonl), the session ID/name/alias, memory files, prior tool-call results. Resuming with --resume/--continue brings the entire history back. In this incident, the session — 5+ weeks of history at the time — was restored intact.
  • Lost: any in-flight turn at the moment of kill (partial assistant output, partial tool calls). For background/long-running tool tasks (Bash run_in_background, etc.), in-flight state is also lost.
  • Manual re-do: the Remote Control pairing — must run /remote-control again after restart, and the iOS app shows the session as disappeared-and-reappeared.

For a power user this is tolerable. For a casual user who's mid-conversation, the iOS UI freeze probably looks like a hard failure with no obvious recovery — they wouldn't know to drop to the laptop and kill the claude process.

Secondary incident — same day, different failure mode, same family

Important sequencing: this second incident occurred after the post-/compact workaround above had successfully recovered the first incident. The same claude session was running normally for ~3.5 hours after the first recovery, then this second, distinct failure happened with no obvious trigger.

Timeline reconstructed from the session JSONL (all times PT):

TimeEvent
~12:00 May 9First incident: post-/compact UI freeze (the primary bug above). Workaround applied (kill+restart+--resume+/remote-control).
12:22 May 9Workaround success confirmed. Conversation resumes normally on the new pairing.
12:22 → 16:00 May 9~3.5 hours of normal operation on the recovered pairing. iOS UI working, messages flowing both ways.
16:00:21 May 9system event: Remote Control disconnected: Transport closed (code 4092). Application-level WebSocket close code, not a standard code. No retry, no auto-reconnect, no notification surfaced to the CLI side.
16:00 → 20:26 May 94.5-hour silent window. Zero session activity. Messages sent from the iOS app during this window had no live pairing to land on; the desktop claude session was idle and unaware.
20:26 May 9User manually ran /remote-control on the desktop terminal. CLI created a fresh pairing (Pairing #4 — exact ID redacted; available privately on request).
20:28 May 9User sent first message after the manual repair. Worked normally.
2026-05-10 morningiOS app showed two entries for this session: the new (Connected, "Today" bucket) pairing and the old (Disconnected, "Yesterday" bucket) pairing — the old one never garbage-collected.

The post-recovery normal-operation window (12:22 → 16:00) confirms the first-incident recovery was real and the second incident is a separate failure mode, not a re-emergence of the first.

Why this matters for triage

  • Same machine, same day, same claude process, same iOS app version, same setup as the post-/compact bug above. Two distinct Remote Control reliability failures within ~12 hours.
  • Different failure mode: this one is a transport-level silent disconnect with no auto-reconnect, vs. the morning bug's post-/compact UI freeze with stale tool indicators.
  • Closer match to existing issue #34255 ("silent connection drops, no auto-reconnect"). The morning bug is closer to #40388. The fact that we hit both classes back-to-back suggests Remote Control's reconnect / state-resync logic has multiple unfixed seams.
  • Cost of recovery here was lower than the morning bug — just /remote-control again, no process restart needed. But during the 4.5-hour silent window, the mobile UX was indistinguishable from "Claude is just slow today" — no error, no auto-recovery prompt. A casual user would assume the assistant had hung and not realize it was a connectivity issue.

Suggested follow-up

Beyond fixing the post-/compact race itself, two separate observability gaps would help:

  1. iOS-side error surfacing when the WebSocket transport closes with a 4xxx app-level code — at minimum a non-modal banner ("Connection lost. Tap to reconnect.") rather than a silent pulsing icon.
  2. Old/disconnected pairings should be auto-pruned from the iOS session list after some TTL, or at least visually de-prioritized — otherwise users accumulate stale entries and have to guess which one is live.

Related issues

  • #40388 — Remote Control mobile stuck on "sending" after /clear. Same class (slash-command-induced state mismatch between server and mobile client); closed as duplicate without a master link. The post-/clear and post-/compact cases may share root cause.
  • #28926 — Remote control infinite loading loop on mobile client (closed stale).
  • #52796 — Remote Control session unresponsive after first command from mobile app (open).
  • #34255 — Silent connection drops, no auto-reconnect (open).
  • #28571 — Fails to resync after connection drop (open).
  • #20696 — Compaction deadlocks chats on claude.ai web/mobile (different surface — claude.ai chat, not Code Remote Control — but pairs the same trigger word with the same UI symptom).

Hypothesis

The mobile client is keeping state for the pre-compact stream (the Write tool indicator, the pulsing icon) and never receives a "stream finalized → reset → next stream starts here" event from the server, so the post-compact stream doesn't get rendered. Whatever event coordinates /clear and /compact boundaries between server and mobile likely has a race window.

Severity

Medium-high — but scoped to a specific intersection: power users who BOTH (a) run long sessions that rely on /compact to manage context, AND (b) want to monitor or interact with those sessions via the iOS Claude Code Remote Control mobile app. For users who don't use Remote Control, the bug is invisible — the macOS claude session continues working fine. For users who do, the mobile app becomes effectively unusable for the rest of the affected session post-/compact, with no in-UI indication that the freeze is a connectivity issue versus the assistant just being slow.

The secondary incident (transport disconnect, no auto-reconnect) further narrows the practical reliability of Remote Control even outside the /compact trigger.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix iOS Remote Control: mobile UI stuck on pulsing thinking-icon after `/compact`; stale tool indicators remain; no recovery via app reload [2 comments, 2 participants]