Background subagent reports appear lost during mid-turn delivery (absorbed_mid_turn), Windows CLI 2.1.299
Summary
Background subagents finish their work and submit complete reports through SubagentHandback, but the parent conversation sometimes continues waiting for those reports.
In the failing cases, the parent transcript records:
enqueue agent-message + task-notification
remove, reason: absorbed_mid_turn
attachment, type: queued_command
[parent continues saying it is waiting for the agent]
The reports remain recoverable from the subagents' JSONL files. In a four-agent batch, two reports arriving during the parent's ongoing work took this attachment path and were apparently missed; two arriving between parent turns became ordinary user-role peer messages and were received.
Important evidence boundary: remove without dequeue alone does not prove loss. These records explicitly say absorbed_mid_turn, and the report is present in a rendered attachment. I have not captured the outgoing API requests, so I cannot yet distinguish a missing attachment during request construction from a presentation/model-consumption problem. The confirmed symptom is completed work whose report the parent does not act on, despite recording the handback locally.
Environment
- Windows, interactive Claude Code CLI; affected transcript entries identify the entrypoint as
cli. - Locally verified affected versions: 2.1.278, 2.1.280, 2.1.293, and 2.1.299.
- Most recent verified occurrence: 2026-10-14, version 2.1.299.
- The observed parent entries use
permissionMode: auto. ANTHROPIC_BASE_URLpoints to a local proxy. The proxy is configured/reported to forward/v1/messagesbodies unchanged; this report does not independently establish that the endpoint/provider is irrelevant.- Custom model configuration: the latest parent transcript identifies a GLM-5.3 model, and the subagent identifies a DeepSeek-V4.1-Flash model. The September batch also used DeepSeek-V4.1-Flash.
- I have not reproduced this on a direct Anthropic endpoint with Claude-native models.
All timestamps below are UTC. Paths and report payloads are redacted. Line numbers refer to the local transcript snapshots, not a publicly attached full transcript.
Reproduction conditions
This is an observed reproduction pattern, not yet a clean standalone repro:
- Have the parent use the
Agenttool to start background work, including multiple agents in parallel. - Keep the parent working in its current turn with Read/Grep/Bash or other tool calls, rather than ending its turn immediately.
- Have a child finish and submit its substantive final report through
SubagentHandbackwhile the parent is still active. - Observe the queue-operation and attachment records, then whether the parent recognizes the completed report.
In the recorded calls, the Agent input omitted run_in_background; the harness nevertheless returned an asynchronous-launch acknowledgement and ran the agent in the background. The report is about that observed background execution, not a claim that every call explicitly set the flag.
Case A: 2.1.299, 2026-10-14
Parent transcript: ~/.claude/projects/<project>/<session>.jsonl.
Child transcript: ~/.claude/projects/<project>/<session>/subagents/agent-a1c74891359cffa5e.jsonl.
| Time (UTC) | Evidence |
|---|---|
| 09:47:11.749 | Parent calls Agent, then continues its own work. Parent L18101; asynchronous-launch acknowledgement at L18108. |
| 09:49:34.440 | Child calls SubagentHandback with its complete report. Child L120. |
| 09:49:36.896 | Report-bearing agent-message is enqueued. Parent L18139. |
| 09:49:36.905 | Completion task-notification is enqueued. Parent L18140. |
| 09:53:53.691 | Both queue entries are removed with reason absorbed_mid_turn. Parent L18147-L18148. |
| Following those records | Both payloads are present as queued_command attachments. Parent L18149-L18150. Their embedded timestamps retain the original enqueue times. |
| 09:55:08.170 | Parent says “等待摸底代理返回。” (“Waiting for the reconnaissance agent to return.”) Parent L18197. |
| 09:55:59.352 | Parent says “摸底代理仍未返回。” (“The reconnaissance agent still has not returned.”) Parent L18224. |
| 09:59:08.610 | User intervenes: “代理返回了 又被你吞了” (“The agent returned and its report was swallowed again”). Parent L18312. |
| 2026-10-15, 01:49:41-01:49:47 | Parent manually extracts the report from the child's SubagentHandback arguments through Bash. Parent L18376-L18377. |
Sanitized queue excerpt; [report omitted] replaces private project content:
{"type":"queue-operation","operation":"enqueue","timestamp":"2026-10-14T09:49:36.896Z","content":"<agent-message from=\"a1c74891359cffa5e\">[report omitted]</agent-message>"}
{"type":"queue-operation","operation":"remove","timestamp":"2026-10-14T09:53:53.691Z","reason":"absorbed_mid_turn","content":"<agent-message from=\"a1c74891359cffa5e\">[report omitted]</agent-message>"}
The child ends with a successful SubagentHandback tool result stating that the report was delivered to its caller. Its final record is that tool result, not a final assistant-text message or an API error.
Three distinguishing fragments from the report do not appear in the parent's ordinary user/assistant text blocks. They appear in the subsequent manual-recovery tool result at L18377. The earlier queue and attachment records already contain the full report.
Case B: 2.1.280, 2026-09-24, four-agent comparison
The same parent transcript records four Agent calls in one assistant message at 02:16:59.345 UTC, L12820. The parent continues working while the children run.
| Child ID | Report enqueued (UTC) | Observed delivery path | Outcome |
|---|---|---|---|
| a2032e85bbd258b83 | 02:18:05.640 | L12917 enqueue → L12931 remove at 02:18:13.807, reason absorbed_mid_turn → L12933 queued_command attachment | Apparently missed; later manually recovered |
| ad69c934aa3c57e1b | 02:19:32.763 | L12981 enqueue → L12990 remove at 02:20:15.820, reason absorbed_mid_turn → L12992 queued_command attachment | Apparently missed; later manually recovered |
| aebc967825cbc0112 | 02:21:27.848 | L13023 enqueue → L13024 dequeue at 02:21:27.865 → L13025 user-role peer message | Received normally |
| a9e02e256c3d18d44 | 02:23:22.848 | L13083 enqueue → L13084 dequeue at 02:23:22.870 → L13085 user-role peer message | Received normally |
All four children submitted substantive reports through SubagentHandback, and their transcripts end normally with end_turn.
For the two apparently missed reports, distinguishing report fragments only appear in later manual-recovery tool results: L13320/L13328 and L13327. For the two successful controls, the fragments appear directly in the incoming user-text messages at L13025 and L13085.
This is a useful within-session comparison, although it does not establish that parent busy/idle state is the only possible causal difference.
Other cases
| Date | Version verified in child/transcript records | Child | Queue evidence |
|---|---|---|---|
| 2026-09-21 | 2.1.278 | a48a8c70527dc3859 | 05:40:12.440 enqueue, L7447 → 05:40:31.187 remove/absorbed_mid_turn, L7450 → queued_command attachment, L7452 |
| 2026-09-21 | 2.1.278 | af76faec7ab430ad3 | 06:33:58.659 enqueue, L7862 → 06:34:20.165 remove/absorbed_mid_turn, L7865 → queued_command attachment, L7867 |
| 2026-10-12, another session | 2.1.293 | a905031776816205c | 03:18:45.151 enqueue, L142 → 03:25:13.584 remove/absorbed_mid_turn, L152 → queued_command attachment, L155 |
The October 12 session also has a successful control, a71bdfafa19094d8c: report enqueued at 03:30:10.691, with a dequeue record at 03:30:46.739 and an incoming user-role peer message at L275.
Together with Cases A and B, these are six apparently missed reports, with complete handbacks preserved in the child transcripts.
Mechanism: observation versus hypothesis
Observed:
- The failing reports follow the
absorbed_mid_turnattachment path. - The successful controls become user-role peer messages.
- SubagentHandback reports success, but the parent continues behaving as if the report has not arrived.
- The report payload survives on disk and can be recovered manually.
Hypothesis to investigate:
The report may be lost or become ineffective between rendering the queued attachment and consumption by the parent model. Possibilities include omission from request construction, incorrect placement/role, or model interpretation of the injected content.
I am not claiming that the queue never drains, that remove is inherently erroneous, or that absence of a normal user-text record proves absence from the API request.
Verification steps
- Inspect the parent JSONL's queue-operation records and correlate report-bearing agent-message entries with their task IDs and subsequent attachment records.
- Inspect the child's SubagentHandback arguments and successful tool result.
- Compare report-bearing queued_command attachments with successful user-role peer-message deliveries.
- Search distinguishing report fragments separately in normal user/assistant text, tool results, and attachments. Do not treat absence from normal text as proof that the model never received an attachment.
- Compare parent behavior before and after manual report recovery.
- To establish the exact failure point, capture the subsequent outgoing messages request and verify whether it contains the rendered handback. That final request-level check has not been performed for these incidents.
Empty temporary tasks/*.output files are not the evidence used here. The reports were recovered from the child JSONL files.
Expected behavior
Every successful SubagentHandback should make the report reliably available to the parent, whether the parent is busy or idle. If delivery fails, surface an explicit error or retain a retrievable pending report rather than returning an unqualified delivery-success acknowledgement.
Workaround
- As a timing mitigation, end the parent's turn promptly after launching background agents. The observed idle-path controls worked, but this is not a proven delivery guarantee.
- If a report appears missing, extract the existing
SubagentHandback.input.messagefromsubagents/agent-<id>.jsonland have the parent read it instead of rerunning the work.
Related issues
- #86365 — open; child completion notifications apparently lost while the parent is mid-turn, primarily involving forked /code-review coordinators.
- #87675 and #88545 — closed reports with closely matching busy/idle timing.
- #102220 — open; 2.1.296, Linux headless sessions, where queued_command attachments reportedly do not reach the model.
- #97575 — open; interactive CLI example where queued_command content is present but misinterpreted as tool output.
This report adds Windows interactive CLI evidence through 2.1.299, including report-bearing agent-message handbacks, local line references, and successful delivery controls. These may share a cause, but that has not been established.