Cross-session send_message never reaches the receiving agent: the UI renders the message, the session never learns it exists (both when the recipient is idle and when it is actively working)

Status Closed — duplicate
Reported on v2.1.229
Maintainer reply None cached
Activity 2 comments · opened Aug 17, 2026 · closed Aug 25, 2026

Summary

Messages sent with the session-management send_message tool never reach the receiving agent. The recipient's window renders a message card and the sender's tool call returns Message sent, but the receiving session never learns the message exists: it is not written to the recipient's transcript, it does not appear in the recipient's input queue, and asking the receiving agent afterwards returns a truthful "I have no messages".

This happens whether the recipient is idle or actively working, with two different observed failure paths. Both are documented below with the app's own logs.

The net effect is that cross-session messaging does not work at all on this machine. The only way we have found to move content between sessions is for the human to select the rendered card, copy the text, and paste it into the recipient's prompt by hand.

---

Variant A — recipient is idle: cold start hangs 1018s, then the message is discarded

Sent 2026-08-17 04:03:00 local (UTC−3) from local_7d13dae5-2bc0-4f72-a825-9eb301a501a5 ("Metodología de QA - 0816") to local_b46f4131-275d-4808-8722-6cb32568c3db ("WhatsApp MCP 02"), which had been idle since 2026-08-15T23:55:49Z.

From %APPDATA%\Claude\logs\main.log:

04:03:00 [info] Resuming session local_b46f4131-275d-4808-8722-6cb32568c3db in C:\IA\Projects\whatsapp-mcp
04:03:00 [info] Starting local session local_b46f4131-275d-4808-8722-6cb32568c3db in C:\IA\Projects\whatsapp-mcp
04:03:01 [info] [CCD] Passing 21 plugin(s) to SDK (skills: 1, remote: 14, local: 6)
04:03:01 [info] Using Claude Code binary at: C:\Users\fferdgelis\AppData\Roaming\Claude\claude-code\2.1.229\claude.exe

   … 1018 seconds, no further log line for this session, no error, no warning …

04:19:59 [warn] [CCD] Session local_b46f4131-275d-4808-8722-6cb32568c3db timed out after 1018s of inactivity
                 (hadFirstResponse=false, last_message_type=user, last_tool_name=none, seconds_since_stderr=never)
04:19:59 [info] [CCD CycleHealth] unhealthy cycle for local_b46f4131-275d-4808-8722-6cb32568c3db
                 (1018s, hadFirstResponse=false, reason=no_response)
04:20:00 [info] Session local_b46f4131-275d-4808-8722-6cb32568c3db query iterator completed

1018s counted back from 04:19:59 lands exactly on 04:03:01, the cold start. last_message_type=user shows the cross-session message was accepted as that turn's input. It is never persisted and never answered.

Recipient transcript: %USERPROFILE%\.claude\projects\C--IA-Projects-whatsapp-mcp\8a8b96dc-1f33-4532-9385-d34b40f20937.jsonl. Its last three records are all from 2026-08-15T23:55:xx Z. Nothing from 17/08 exists. The unique marker sent in the message (TEST-DESPERTAR-9M2K-20260817) appears 0 times.

---

Variant B — recipient is active and in use: the message never enters its queue

Earlier the same night, three messages were sent from the same source session to local_7419b6e5-76d0-48c1-b089-52d4d073a5ea ("WhatsApp MCP-03") while its operator was actively working in it — so there was no cold start involved.

That session keeps an input queue recorded in its own transcript as queue-operation records with enqueue / dequeue. Inspecting it: every message the human typed and every task notification has an entry. None of the three cross-session messages has any entry at all.

The same asymmetry was measured in the reverse direction. Session "Metodología de QA - 0815" sent two messages to "Metodología de QA - 0816". The recipient's transcript (27d6c122-714b-4c3c-b879-bdd116c4831a.jsonl, 1817 lines, 162 queue-operation records of which 79 are enqueue) contains no queue-operation with a real timestamp inside either send window (06:37:xx, 06:38:xx UTC). The queue mechanism itself works normally; these messages simply never enter it.

For that pair the tool returned two different strings seconds apart:

Message sent to session …
Message queued for session …; it will be processed after the in-flight turn finishes if that session stays healthy.

Neither was delivered, so the distinction did not predict the outcome.

Contamination disclosed: to keep the investigation moving the human relayed content by hand, so plain text-occurrence counts across transcripts are no longer a valid control. The absence of enqueue records inside the send windows is unaffected — the manual paste produced its own enqueue with its own timestamp (06:43:00), which is exactly why it cannot be mistaken for a delivery at 06:37/06:38.

Raw queue log of the recipient, across the window where the two messages should be

Extracted from 27d6c122-714b-4c3c-b879-bdd116c4831a.jsonl (the recipient's own transcript), all queue-operation records with a timestamp in 06:2x06:5x UTC. Timestamps are UTC; the two messages were sent at 06:37:25Z and 06:38:31Z:

06:23:28  enqueue
06:23:28  dequeue
06:25:09  enqueue   De hecho, hagamos una cosa porque estoy centralizando c…
06:25:09  dequeue
06:28:40  enqueue
06:28:40  dequeue
06:33:56  enqueue   Mediciones crudas. Empiezo por ubicar el archivo. Lo…
06:33:56  dequeue
                    <-- 06:37:25Z and 06:38:31Z: the two cross-session
                        messages. No record of any kind.
06:42:01  enqueue
06:42:01  dequeue
06:42:01  enqueue
06:42:01  dequeue
06:43:00  enqueue   Mandados los dos mensajes. Y en el camino salieron tres…
06:43:00  dequeue
06:54:55  enqueue   dale, mostrame el ticket final
06:54:55  dequeue
06:58:23  enqueue   No existe ninguna sesión llamada 0815. Revisé las 56 se…
06:58:23  dequeue

Every human prompt produces a matching enqueue/dequeue pair. The two cross-session messages produce nothing. Note 06:43:00 — that is the human pasting the content by hand, which enqueues normally and carries its own timestamp.

The same file holds 186 queue-operation records in total, so the mechanism is plainly working.

The other recipient's queue log, as reported by that session

Session "WhatsApp MCP-03", inspecting its own transcript after being asked whether it had received three cross-session messages, reported its last queue operations as:

02:44:06  enqueue   dale, hacé el relevamiento de P3.1 mientras tanto
02:44:06  dequeue
03:23:39  enqueue   pregunta 1, opcion B…
03:23:39  dequeue
05:34:00  enqueue   lee los mensajes que te llegaron de Metodologia de QA
05:34:00  dequeue

Its own summary: "Everything you type enters and is delivered. Task notifications too. The two messages from the QA session have no entry. Not one."

The entry at 05:34:00 is the human telling it to go and read the messages — the instruction enqueued normally; the messages themselves never did.

---

Steps to reproduce

Variant A: open two local sessions A and B; leave B idle until isRunning: false; from A call send_message targeting B. B renders a card, isRunning flips to true, a turn timer starts, nothing is ever produced. After ~1018s the timer stops, isRunning returns to false, and a warning icon appears next to B in the sidebar. B's transcript has no record of the message.

Variant B: same, but with B actively in use. The card renders; B's queue never receives an entry; asking B returns "no messages".

---

What we already ruled out — please do not ask us to retest these

It is not triggered by any user interaction. Three phases were measured on the same message, polling B's transcript for line count, enqueue count and the unique marker:

| Phase | Stimulus | Duration | Samples | Result |
|---|---|---|---|---|
| 1 | none — window untouched | 5.5 min | 11 | 764 lines / 20 enqueue / 0 marker — no change |
| 2 | clicks all over B's window | 16 min | 20 | identical |
| 3 | Print Screen + screen-capture tool | 4 min | 24 | identical |

55 samples, three stimuli, zero variation. Giving the window focus does not deliver the message; neither does anything else the user can do.

It is not "queued behind an in-flight turn". In Variant A the recipient was idle and had been for over a day. In Variant B the queue log shows no entry was ever created, at any later time.

It is not a write lag. 17 minutes elapsed with the recipient's file untouched after the initial cold-start write.

The queue mechanism is not broken generally. The two recipients hold 162 and 168 queue-operation records respectively; everything the human types enqueues normally.

Nothing is logged as an error. Between the cold start and the timeout there is no [error] or [warn] line for that session — only unrelated entries (a scheduled-tasks VM warning, a duplicate-plugin warning, a git fetch failure in a different project).

The app does detect the failure, but only marks it as an unhealthy cycle and shows a warning triangle next to the session in the sidebar, 17 minutes after the fact, with no text and in a place nobody watches.

---

Two session-id namespaces — needed to read the evidence

The app log states the mapping explicitly:

04:02:24 [info] Mapping internal session local_7d13dae5-2bc0-4f72-a825-9eb301a501a5
                to CLI session 27d6c122-714b-4c3c-b879-bdd116c4831a

The local_<uuid> id returned by list_sessions is not the transcript filename. In %USERPROFILE%\.claude\projects\C--IA-Projects-framework-multi-ai\ the only .jsonl files are 0c794dbc, 27d6c122, 9e249fb4 and c02acd42; neither routing id appears as a filename. Without this, the file evidence above reads as missing files.

---

Secondary issues found while investigating

The phantom turn blocks real user input. While a recipient sits in this state, anything the human types queues behind the never-completing turn. In one case the human had to press Interrupt to cancel a turn that had never existed before his own message would run. So a cross-session message does not merely fail — it freezes the receiving session for ~17 minutes.

The transcript-reading tool shows the message anyway. The session-management "read another session's transcript" tool returns the message as a [user] turn wrapped in <cross-session-message from="…" name="…" encoded="1">, even though the recipient's .jsonl contains no such record and the recipient agent never saw it. That read path and the file the running agent reads disagree. This caused an investigating agent to conclude twice, wrongly, that delivery had succeeded.

---

Impact

Every user-visible layer reports success: the sender's tool returns "Message sent", the card renders in the recipient's window, the spinner runs. Nothing indicates failure until someone notices a stalled timer.

Concretely, in this setup: one session performs QA and reports defects to another session that writes code. Three structured defect reports were closed on the sending side as delivered while the receiving session had never seen them. They were only recovered because the human noticed the stalled spinner and pasted the text by hand.

The purpose of the feature is to let two sessions coordinate without a human relaying text. As it stands the human is the transport, and the recipient is frozen while he is not looking.

A visible error, a retry, or simply not rendering the card would all be far safer than the current behaviour.

---

Environment

  • Claude Code desktop app on Windows 11 Pro 10.0.26200
  • Claude Code CLI 2.1.229 (…\AppData\Roaming\Claude\claude-code\2.1.229\claude.exe)
  • Model claude-opus-5; sender at effort high, one recipient at high, another at max
  • All sessions local (isRemote: false), same machine, same OS user
  • Projects involved: C:\IA\Projects\framework-multi-ai, C:\IA\Projects\whatsapp-mcp
  • 21 plugins loaded (skills 1, remote 14, local 6); 59 MCP tools, 18 MCP servers
  • Sessions referenced:
  • local_7d13dae5-2bc0-4f72-a825-9eb301a501a5 "Metodología de QA - 0816" → file 27d6c122-714b-4c3c-b879-bdd116c4831a.jsonl
  • local_24a4bb97-7ad5-4a27-a602-71a1a81c305d "Metodología de QA - 0815" → file 9e249fb4-5560-4ddd-97da-8db28ad9f1f9.jsonl
  • local_b46f4131-275d-4808-8722-6cb32568c3db "WhatsApp MCP 02" → file 8a8b96dc-1f33-4532-9385-d34b40f20937.jsonl
  • local_7419b6e5-76d0-48c1-b089-52d4d073a5ea "WhatsApp MCP-03"
  • Full main.log and the three polling logs are available on request.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗