Remote Control: prompts sent mid-turn never become user turns, so the phone and the terminal show different conversations (re-report of #86980)

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 22, 2026

Summary

With Remote Control connected, a prompt sent from the mobile app while a turn is running is stored only as a queue-operation event. It never becomes a user turn, so it does not render in the terminal / desktop transcript. The same prompt is kept on the connected device, so the phone and the desktop show a different conversation for the rest of the session.

This is a re-report of #86980, which was closed on 2026-09-13 as NOT_PLANNED by the stale-issue bot ("Closing for now — inactive for too long. Please open a new issue if this is still relevant."), not because it was fixed. It is still relevant: measured today on v2.1.x.

What the docs say

code.claude.com/docs/en/remote-control.md sets the expectation that both surfaces show the same thing:

Work from both surfaces at once: the conversation and the progress of subagents and dynamic workflows stay in sync across all connected devices, so you can send messages from your terminal, browser, and phone interchangeably.

and then, under What connected devices see:

Prompts you send mid-turn: when you send a prompt from a connected device before the current turn ends, Claude Code queues it and keeps it in the device's transcript after that turn finishes.

That sentence only promises the prompt is kept in the device's transcript. Nothing is said about the terminal's transcript, and in practice it is not kept there. The asymmetry is not called out as a limitation, so a user reading the first quote reasonably expects both sides to match.

What I measured

One long-running session (Windows, Claude Code Desktop, Remote Control on), one day of use, alternating between the desktop and the iOS app.

| | |
|---|---|
| prompts the user sent that day | 22 |
| stored as a user turn (message.content is a string) and carrying a last-prompt event | 10 |
| stored only as queue-operation | 12 |

The split is not random: all 10 that became turns were typed while the session was idle, and all 12 that did not were typed while a turn was running — most of them from the phone.

Event shapes in ~/.claude/projects/<project>/<session>.jsonl:

# typed while idle -> a real turn
{"type":"user", "message":{"content":"<the prompt text>"}, "origin":..., "promptSource":...}
{"type":"last-prompt", "lastPrompt":"<the prompt text>"}

# typed mid-turn -> queue only
{"type":"queue-operation", "content":"<the prompt text>"}
{"type":"attachment", "attachment":{"prompt":"<the prompt text>"}, "rendered":[...]}

There is no user event whose message.content is the prompt string, and no last-prompt event, for any of the 12.

Why this matters beyond display

The prompt still reaches the model — the attachment is surfaced into the running turn, so Claude acts on it. The problem is the record:

  1. The two surfaces disagree. Returning to the desktop after working from the phone, the user sees assistant messages responding to instructions that are not visible anywhere in that transcript.
  2. Authorizations become hard to audit. In my case those 12 prompts included permission to close specific applications on the user's machine. The assistant's replies reference that permission; the desktop transcript does not show it being given.
  3. Compaction. Because the text lives inside queue-operation / attachment records rather than a user turn, it is not obvious that it survives a compaction boundary the way a normal user turn does. A session that compacts repeatedly can lose the instruction while appearing to have full context.

Reproduction

  1. Start an interactive session and connect a device with Remote Control.
  2. Give Claude a task that runs for a minute or more.
  3. While it is running, send a prompt from the phone.
  4. Let the turn finish.
  5. Look at the terminal/desktop transcript: the prompt is not there as a message.
  6. Look at the session .jsonl: the text appears under queue-operation and attachment, never as user.message.content and never as last-prompt.

Suggested fix

Either write a user turn (and a last-prompt event) for a queued prompt when it is delivered, so both surfaces render the same conversation — or, if the current behaviour is intended, state the asymmetry explicitly in What connected devices see, because the "stay in sync … interchangeably" wording earlier on the same page reads as a promise that they match.

Related

  • #86980 — same behaviour, closed as NOT_PLANNED by the stale bot on 2026-09-13
  • #94457 — desktop app sends mid-turn messages immediately instead of queueing
  • #95343 — Remote Control (mobile): cross-device session state does not sync

View original on GitHub ↗