◉CLAUDE LABJP
●CODE 2.1.322 — Fast mode now works on Vertex in the global, us and eu regions (11/10), falling back to standard speed if refused●FABLE 5.2 — Claude Code 2.1.321 makes Fable 5.2 the default Fable model: 1M context at $8/$40 per Mtok●MANAGED — Self-hosted Claude Managed Agents is out (11/12): you run the whole service yourself●SONNET 4.5 — Retires on the Claude API on 11/30, 17 days left. Migrate to Sonnet 5.5●MCP APPS — Users report local MCP app views no longer showing in Chat after a desktop update●NEW — Cowork or Claude Code First, With No Terminal Experience●CODE 2.1.322 — Fast mode now works on Vertex in the global, us and eu regions (11/10), falling back to standard speed if refused●FABLE 5.2 — Claude Code 2.1.321 makes Fable 5.2 the default Fable model: 1M context at $8/$40 per Mtok●MANAGED — Self-hosted Claude Managed Agents is out (11/12): you run the whole service yourself●SONNET 4.5 — Retires on the Claude API on 11/30, 17 days left. Migrate to Sonnet 5.5●MCP APPS — Users report local MCP app views no longer showing in Chat after a desktop update●NEW — Cowork or Claude Code First, With No Terminal Experience
Articles/Claude.ai
◉ Claude.ai/2026-11-13Beginner

Your iPhone Correction Arrives Only After the Turn Ends — Spotting Remote Control's Queue-for-Later and Steering Again

When a correction sent from the Claude iOS app to a session running on your Mac waits until the turn ends: how to recognize it, where the version boundary is, workarounds that avoid Stop, and a small script that counts the wait from the session transcript.

Remote ControlClaude iOSClaude Desktop4Troubleshooting26Session Management4

On Friday morning I finished reading a GitHub issue and just sat there for a moment.

The report said that messages sent from the iPhone app while Claude is working no longer reach it until the turn ends. I do this all the time: hand a long job to the Mac, step away, and send a one-line "skip that part for now" from my phone. If that line had been sitting in a box until the very end, my correction was really just a note read after the fact.

Here is what I worked out: how to recognize the symptom, the order I'd check causes in, how to get a message through without stopping the run, and what to do if none of that helps. It's based on the reporter's measurements and a small checking script I wrote and ran myself.

Recognize it first — the composer text is the tell

The quickest check is the faint placeholder text in the iOS app's composer.

StateComposer showsWhere your message goes
Claude is idleType / for commandsDelivered right away
Claude is workingQueue for after this turn…Held until the turn ends

If you send several messages mid-turn, they are handed over together at the end of the turn, as a single message. When you sent three separate notes and the reply reads like it took them all in at once, this is the symptom to suspect.

No error appears anywhere. That's exactly why it's easy to miss — it just feels like Claude ignored you.

Narrow it down — the line is 2.1.321

The reporter (issue #108975) swapped only the Claude Code build bundled with the desktop app and ran the same test each time: Claude runs one 5-second tool call after another while messages are sent from the iPhone.

Claude CodeMid-turn messages from iOS
2.1.309Delivered at the next tool result (3/3)
2.1.319Delivered at the next tool result (4/4, then 8/8)
2.1.321Held until the turn ended (7/7)
2.1.322Held until the turn ended (7/7)

According to the reporter, 2.1.321 fixed a bug where a Remote Control message sent with "Queue for later" reached Claude in the middle of the running turn. That fix is correct on its own. The catch is that the iOS app marks every mid-turn message as "later" and offers no send-now option the way the desktop does.

I'd check things in this order:

  1. Was the message sent from the iPhone (or iPad) app? Terminal and Mac app sends aren't affected
  2. Did the composer read "Queue for after this turn…"?
  3. Which Claude Code version is Claude Desktop running on the Mac? 2.1.321 or later matches
  4. If the same thing happens from the terminal or Mac app, look for a different cause

For reference, the terminal still slips a typed message in after the running tool call, and the Mac app shows "Send now" on a queued message. Right now, only the phone is stuck.

Count whether it was really held

Rather than stopping at "it felt slow," it helps to check the record — both for adding to the issue and for your own judgment. Claude Code's session transcript (usually a .jsonl under ~/.claude/projects/) logs messages sent during a turn as queue-operation lines.

This script pairs each send time with the time Claude received it, and flags messages that were delivered as a batch.

#!/usr/bin/env python3
"""Count how long each message waited before Claude received it, from a session .jsonl"""
import json
import sys
from collections import Counter
from datetime import datetime
from pathlib import Path
 
 
def parse_ts(value):
    # fromisoformat in Python 3.10 and earlier can't read a trailing Z
    return datetime.fromisoformat(value.replace("Z", "+00:00"))
 
 
def load_queue_events(path):
    events = []
    with open(path, encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            try:
                row = json.loads(line)
            except json.JSONDecodeError:
                continue  # skip a half-written last line
            if row.get("type") != "queue-operation":
                continue
            ts, op = row.get("timestamp"), row.get("operation")
            if ts and op:
                events.append((parse_ts(ts), op))
    return sorted(events)
 
 
def main():
    if len(sys.argv) != 2:
        sys.exit("usage: queue_wait.py <session.jsonl>")
    events = load_queue_events(Path(sys.argv[1]).expanduser())
    if not events:
        print("No queue-operation lines found (nothing sent mid-turn, or the format differs)")
        return
 
    waiting, delivered = [], []
    for ts, op in events:
        if op == "enqueue":
            waiting.append(ts)
        elif op == "dequeue" and waiting:
            delivered.append((waiting.pop(0), ts))  # assume first sent, first delivered
        elif op == "popAll":
            delivered += [(sent, ts) for sent in waiting]
            waiting = []
        # "remove" marks things like notifications absorbed mid-turn, not human sends
 
    batch = Counter(got for _, got in delivered)
    print(f"{'sent':<10} {'received':<10} {'wait(s)':>8}")
    for sent, got in delivered:
        wait = (got - sent).total_seconds()
        mark = f"  <- delivered with {batch[got] - 1} other(s)" if batch[got] > 1 else ""
        print(f"{sent:%H:%M:%S}   {got:%H:%M:%S}   {wait:8.0f}{mark}")
    if waiting:
        print(f"\nStill waiting: {len(waiting)} message(s)")
 
 
if __name__ == "__main__":
    main()

Run it as python3 queue_wait.py ~/.claude/projects/<folder>/<session-id>.jsonl. When I fed it a transcript recreating the timestamps from the report, the three messages that had waited 7 to 13 seconds all came back flagged as delivered together.

The point I want to leave you with: look at whether messages arrived as a batch, not at how long they waited. When the turn is a string of short tool calls, a held message can still arrive within seconds. Go by seconds alone and you'll miss it; several messages landing at the same instant is the footprint of waiting for the turn to end. The transcript format may change between versions, so the script says so plainly when it finds no queue-operation lines at all.

Getting through without pressing Stop

Until an official fix lands, this is the order I'd reach for:

  1. If the Mac is nearby, press "Send now" in the desktop app. It switches a queued message to immediate delivery
  2. Join the same session from claude.ai in a browser. The reporter says the web composer offers "↩ to send, ⌘↩ to queue for later," and a plain send arrives mid-turn. I haven't yet confirmed whether a phone browser shows the same choice
  3. Ask for checkpoints up front on long jobs. Held messages are released when a turn ends, so shorter turns give your corrections more chances to land

The third one only takes a few lines at the end of your request:

Please work in three stages.
After each stage, report what you changed in three lines and end your turn.
If I don't reply, go ahead with the next stage.

Each turn now ends at a "report and pause" point, so a correction from the phone gets read at the end of that stage. It's a little more back-and-forth, but far easier on the stomach than watching a job keep going in the wrong direction.

A correction that never arrives is the same as one never sent. So the more likely a job is to need steering, the shorter I make its turns.

When nothing helps — and what I chose not to do

Stop is the last resort. It cuts off the running tool call, and whatever it was in the middle of is lost. If you stop during a file edit, check the diff before asking it to continue.

The reporter restored the old behavior by swapping the bundled Claude Code for the 2.1.319 binary. I've decided not to copy that. An app update will overwrite it, and you'd also give up the other fixes that shipped in 2.1.321. As an indie developer who leaves my own site and app operations running for long stretches, I'd rather not create a setup that works but whose version I can't vouch for — that tends to cost more later.

The next step is to leave a reaction on issue #108975 with your environment (Claude Code version, iOS app version) and the numbers from the script above. The more matching reports pile up, the easier it is for a fix to move up the list. If you're setting up Remote Control for the first time, I wrote about that in If You Walk Away While Claude Code Is Running, Turn On Remote Control First.

For today, try sending one line from your iPhone while a job is running, and just look at what the composer says.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◉ Claude.ai2026-08-29
The 30-Day Session Cleanup Is Fixed, and It Made Me Rethink Where I Keep Records
Claude Desktop and Cowork sessions were quietly disappearing after 30 days until v2.1.248 fixed it. Here is how to check your own setup, what the new setting actually caps, and a small journal script that keeps one line per run outside the session.
◉ Claude.ai2026-10-06
Paid for Pro but still on Free? Where you bought it decides which screen to open and where to cancel
You paid for Claude Pro but the account shows Free, there is no invoice, or there is no Cancel button. A side-by-side of web/Desktop purchases versus iOS/Android in-app purchases, so you know which screen to open first for each symptom.
◉ Claude.ai2026-10-03
My Usage Limit Ran Out Before Noon, and the Reason Was Conversation Length, Not Message Count
When the usage-limit banner shows up on Pro or Max sooner than you expected, here is the order I check: the two bars in Settings > Usage, the length of the conversation and its attachments, then the model and effort level. The morning I got cut off before lunch, and the lines I drew afterwards.