[BUG] (Async) Subagents stopping early

Status Closed — not planned
Reported on v2.1.104
Maintainer reply None cached
Activity 11 comments · opened Apr 14, 2026 · closed Jul 21, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Subagents spawned via the Task tool with run_in_background: true can stop executing before completing their work, and the Claude Agent SDK reports them as <status>completed</status> to the parent agent. The parent has no reliable way to distinguish a subagent that finished successfully from one that was terminated prematurely.

I see subagents that:

  • Make anywhere from 5-40 tool calls over 2-10 minutes
  • Were still actively making tool calls when execution stopped (stop_reason: None on final messages)
  • Never reached the final step of their instructions (writing output to a file)
  • Were reported to the parent as <status>completed</status>

Essentially, the agent stopped mid-work, and the SDK told the parent it "completed."

This is a recurring pattern, seems to happen in about 14-30% of agent runs. I do not think this is a prompting issue because it always happens after some tool results - the subagent uses a tool, gets the result, and just stops without producing any output.

What Should Happen?

  1. The SDK should not report completed when a subagent was terminated before it chose to stop. The stop_reason: None on the subagent's final messages indicates the agent did not choose end_turn -- something external ended the session. The task notification should reflect this (e.g., <status>terminated</status> or <status>interrupted</status>).
  1. The task notification should include a stop_reason or termination_reason field so the parent agent can more easily determine what happened and decide whether to retry.

Error Messages/Logs

The task notification for the prematurely stopped subagent:

<task-notification>
<task-id>aaa583525301d9735</task-id>
<tool-use-id>toolu_011KhgSzp2v9Cd9iANWVUUYf</tool-use-id>
<output-file>/tmp/claude-1000/-home-user/tasks/aaa583525301d9735.output</output-file>
<status>completed</status>
<summary>Agent "Research TERN-501 and TERN-801" completed</summary>
<usage><total_tokens>64000</total_tokens><tool_uses>44</tool_uses><duration_ms>143711</duration_ms></usage>
</task-notification>

Compare to a subagent that actually finished its work (also reports completed, but includes a <result> block):

<task-notification>
<task-id>a9969619664ec9d75</task-id>
<tool-use-id>toolu_01HTpSYExfZarv9benv4oFAE</tool-use-id>
<output-file>/tmp/claude-1000/-home-user/tasks/a9969619664ec9d75.output</output-file>
<status>completed</status>
<summary>Agent "Research ORX142 and ORX489" completed</summary>
<result>
All 61 citations passed verification with zero errors and zero warnings. The research notes file is complete and verified.
The research findings have been written to `/home/user/working/research_notes/orexia_assets.md`.
</result>
</task-notification>

The only observable difference is the presence/absence of <result>. The <status> is identical in both cases.

Subagent's final messages before it stopped (from the subagent transcript research-assistant_aaa583525301d9735.jsonl):

The subagent's last three assistant messages all have stop_reason: None (not end_turn), and the agent was actively issuing tool calls:

[assistant] stop_reason: None
TEXT: "Let me read the S-1 for patent expiry details..."
[assistant] stop_reason: None  
TOOL: mcp__local__read_source(source_id: src189)
[assistant] stop_reason: None
TOOL: mcp__local__read_source(source_id: src185)

The agent never chose to stop. It was still working when execution ended.

Steps to Reproduce

  1. Create a parent agent th1at spawns a subagent via the Task tool with run_in_background: true.
  2. Give the subagent a prompt that requires many sequential tool calls before producing output. For example: "Search for and read 15 source documents about [topic], then write a comprehensive summary with citations to /home/user/working/research_notes/output.md."
  3. The subagent will begin actively researching (search, read, search, read...). At some point, execution stops.
  4. The parent receives a task notification with <status>completed</status> and no <result> block.
  5. The output file was never created. The parent discovers this only by checking the filesystem.

Note that it's a relatively transient issue, just one that causes a lot of waste.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.104

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Non-interactive/CI environment

Additional Information

_No response_

View original on GitHub ↗

11 Comments

SaitoPhoenix · 3 months ago

I agree that this is a transient issue, but one of the constant sources of frustration as it continues to be pervasive. This is often a daily issue for me, and though it typically just takes a nudge to get things moving again, I've had times where every single nudge merely made it take one more step to then halt yet again. In some cases, the ask wasn't even large: a single tool call and then a stall. I have found it to be more frequent when a subagent has a larger amount of context, but I have also seen it when there is virtually no context.

DanRxn · 3 months ago

Observed: run_in_background:true sub-agent stalls at WE-class scaffolding scope

Sharing data points that may be relevant to this issue.

Setup: Rory (a CC-based orchestrator agent) dispatches Sonnet sub-agents from scheduled heartbeats to execute multi-file scaffold tasks on a Next.js/Prisma project. Tasks at this scope typically run 28–45 tool uses, touching 8–15 files.

Three background stalls observed:

| Date/Time (PT) | Mode | Tool uses at stall | Final message (truncated) | stop_reason |
|---|---|---|---|---|
| 2026-05-16 19:08 | run_in_background:true | ~41 | "Now create the actions tests:" | None |
| 2026-05-17 05:55 | run_in_background:true | ~28 | "Now let me create the server actions:" | None |
| 2026-05-17 16:13 | run_in_background:true | ~35 | "Now create the actions tests:" | None |

In all three cases: final assistant message was truncated mid-sentence, no <result> block was produced, stop_reason was None, and the parent session reported the sub-agent as "completed."

One foreground success at identical scope:

  • 2026-05-17 20:08 PT — same task type, same model (Sonnet), 35 tool uses (squarely inside the 28–41 stall band), run_in_background NOT set. Completed cleanly in ~6 min wall-clock, produced a full <result> block, opened PR #17.

Conclusion: The stall appears async-specific. Foreground execution at identical scope and tool-use count succeeds where background fails. We are adopting foreground as the default for multi-file scaffolding sub-agents as a workaround pending a fix.

Happy to share additional details if helpful.

kcarriedo · 3 months ago

The 14-30% silent-completion rate is the most damaging part of this — a 1-in-4 to 1-in-7 false-completion rate is enough to make any orchestrator that branches on <status>completed</status> unsafe for production use, but low enough that it passes a casual demo. The orchestrator code that handles a real completion vs. a premature stop looks identical to the orchestrator, and the failure presents as "downstream consumer got bad/empty inputs" — which gets attributed to model quality rather than to a missing transport event.

A few notes from running an out-of-process orchestrator over a similar Task(run_in_background:true) fan-out:

  1. stop_reason: None is the diagnostic primitive but it's not surfaced. The fact that the final message has no model-emitted stop reason is the clearest signal "this was terminated, not finished." Today the SDK collapses that into status: completed at the orchestrator boundary, losing the distinction. Surfacing stop_reason: null | "end_turn" | "max_tokens" | "tool_use" | ... directly to the orchestrator (or, even simpler, a boolean model_chose_to_stop: bool) would let consumers reject the premature-stop case without needing access to the underlying transcript.
  1. The recurring shape "tool result arrives, agent stops" suggests the bug lives at the loop-continuation decision. A subagent that's still mid-trajectory between tool calls but doesn't choose to invoke the next tool is structurally similar to a parent session that hits an injected forcing function and quietly exits (see also #60128 — same shape, different surface). Both are cases where the subagent runtime terminates without an explicit stop reason but downstream consumers are told it completed. A single fix at the runtime's "should I keep going?" predicate would address both — the predicate currently appears to short-circuit on conditions other than explicit model stop, and those short-circuits should at minimum surface a non-completed status.
  1. Workarounds that work for now (none are good substitutes for the fix):
  • Side-effect verification. If the subagent's final step is "write a file" / "post a comment" / "advance a git ref," have the orchestrator verify that side-effect before treating the return as authoritative. This is the only check that's both necessary and sufficient — the subagent's status field can be wrong but the artifact's existence on disk can't.
  • Structured returns instead of free-form. Schema-validate the subagent's return payload. A subagent that quietly stops produces an empty/partial structure that fails validation, surfacing the failure as a validation error rather than a silent pass. Doesn't work for subagents whose output is naturally prose.
  • Independent watchdog. Track per-subagent activity (tool-call counter, last-message timestamp). If a subagent reports completed but its activity counter never reached the expected tail (e.g., the final Write tool call), treat the return as suspect. Heuristic, but catches the modal failure shape.
  1. For the SDK-side fix, the minimum useful change is exposing the underlying stop reason. Even before reconciling premature stops at the runtime layer, surfacing last_message.stop_reason to the orchestrator would let the consumer make the call. A completed status with stop_reason: null is the structural signal "I stopped but the model didn't choose to" — that's the actionable bit, and it's information the SDK already has.
  1. Worth flagging that #60142 is in the same family. That issue describes task_notification(completed) firing before the subagent's ResultMessage — different timing, but the same underlying "completion is being signaled before the subagent's terminal state is durable." Fixing either one in isolation closes only half the surface; fixing the underlying "completion is multi-phase and the orchestrator only sees the first phase" pattern closes both.

The cleanest end-state is: orchestrator subscribes to one event that's emitted only after the subagent's terminal state is durable on the transport stream. Everything else is a hint. Subscribing.

astreet · 3 months ago

+1 to the repro steps above - we consistently see this with subagents that need to do many tool calls (20+). However, we also see it for foreground agents, not just ones run in the background. Agents will receive tool results from some tool call, and then do not take another turn. The subagent transcript ends with the tool results. Most recent stop_reason is tool_use (normal), before it got the tool results. At the least, we'd also like a more clear reason given for stopping!

abhinas90 · 3 months ago

This looks like the kind of bug that shows up when subagent execution is treated as “just spawn more workers” without a strong completion contract.

The first thing I’d check is whether the parent/coordinator has a clear definition of:

  • when a subagent is considered finished,
  • what artifact/result must exist before the parent advances,
  • whether partial progress is being mistaken for completion,
  • how async cancellation / timeout / retry state is being surfaced back upstream.

A practical pattern that helps a lot is:

  1. subagent writes explicit completion artifacts,
  2. parent waits on those artifacts instead of inferred state,
  3. retries are idempotent and task-scoped,
  4. summaries/logs are returned separately from the “done” signal.

In multi-agent systems, the failure is often less about parallelism itself and more about ambiguous lifecycle boundaries between planner and executor.

If this is already on your radar, I’d also look at whether the subagent payload is carrying more bootstrap/context than it needs. Oversized inherited context tends to make async worker behavior less predictable and harder to debug.

guhyun9454 · 2 months ago

Corroborating, plus an extra axis: this splits almost entirely on model tier — and forced structured output is immune.

Confirming this reproduces on foreground (synchronous) Task subagents too, not just run_in_background: true (matching @astreet's note above). I ran a controlled sweep and the loss rate tracks the subagent's model tier far more than anything else.

Setup: Claude Code, subagents spawned via the Task/Agent tool with an explicit per-call model. Each probe is handed a unique marker token and instructed to make that token its entire final message; PASS = the marker actually arrives back at the parent. (Disclosure: my session also has a hook-injecting plugin active — see the last point; it may be a contributing trigger, so treat the absolute rates as environment-flavored, but the cross-model contrast is the signal.)

Sweep A — 96 probes (8 replicates × 3 models × 4 modes):

| model | no-tool (short) | no-tool (long) | one web search | forced structured output |
|---|---|---|---|---|
| opus | 8/8 | 8/8 | 8/8 | 8/8 |
| sonnet | 1/8 | 0/8 | 6/8 | 8/8 |
| haiku | 0/8 | 0/8 | 2/8 | 8/8 |

**Sweep B — 16 probes, a real research subagent (do web lookups, report a version + cite the URL — i.e. genuine free-form prose, the modal use case): opus 8/8 returned the cited report; sonnet 0/8** (all 8 sonnet returns were degenerate).

Across both sweeps: opus 48/48 surfaced, non-opus free-form lost the large majority of the time.

Three observations that may help localize it:

  1. Strongly model-dependent. Opus is effectively immune; sonnet/haiku lose the final free-form message at high rates under otherwise identical conditions.
  1. What comes back instead of the answer is a post-completion idle/wrap-up turn — not a truncation of the answer. Verbatim samples of the captured "final message" when the real result was lost: "(Standing by.)", "(Awaiting new input)", "Task finished.", "Subagent task concluded.", "Acknowledged.", plus several non-English idle phrases like "확인했습니다." ("understood") and "무엇을 도와드릴까요?" ("how can I help you?"). These read exactly like a fresh-turn / idle assistant message. That's consistent with the "completion is multi-phase and the orchestrator only sees the wrong phase" theory in this thread: the real answer turn (the one that should carry end_turn) is being clobbered by a later degenerate turn, and that later turn is what gets surfaced.
  1. **It's the channel, not the content/format — only the free-form terminal text is affected. Forcing the payload through an actual tool call (a schema-constrained StructuredOutput tool call) is 100% immune across all three models (24/24, incl. sonnet & haiku). But this is specifically about the tool-call channel, not** about asking for "structured-looking" text: as a negative control, asking sonnet to make its entire final message a JSON object / fenced ``json block (no tool call, just JSON-shaped prose) still fails — **0/4**, returning the same idle fragments ("대기 중입니다.", "무엇을 도와드릴까요?"`). So the payload surviving has nothing to do with it being JSON; it survives only when it rides in tool-call args instead of the terminal assistant message. Strong hint the defect is in terminal free-form text surfacing/selection, not in the agent loop or output formatting.

A concrete trigger to check: a few of the degenerate captures were literally the subagent answering a hook injection"(duplicate hook — ignoring.)", "(duplicate hook — no action)". In my setup a plugin injects system-reminders into subagents, and it looks like a hook-driven turn fired after the model had already produced its answer can become the "final message." If the runtime can append/force any turn after the model's end_turn, non-opus models tend to answer it with idle filler — and that filler is what surfaces to the parent. Might be worth checking whether SubagentStop / continuation injection can produce a terminal turn after the model has already chosen to stop, and whether the "final message" selection should prefer the last end_turn message over the literal last message.

---

Minimal repro. Spawn the same prompt twice via the Task tool, once with model: "opus" and once with model: "sonnet" (or "haiku"), and compare what comes back to the parent. The exact probe prompts I used (replace <MARKER> with any unique token, e.g. MARK-7f3a):

  • no-tool, short — opus returns the marker, sonnet usually returns an idle line instead:

``
Do NOT use any tools. Your ENTIRE final message must be exactly this single line and nothing else:
<MARKER>
``

  • no-tool, long (marker at the very end — tests tail loss):

``
Do NOT use any tools. First write exactly three sentences about the number seven. Then, on its own final line, output exactly this and nothing after it:
<MARKER>
``

  • one web search (the modal failing case):

``
Do EXACTLY ONE web search for "current stable version of curl", then STOP searching (no more tool calls). Your ENTIRE final message must be exactly this single line and nothing else:
<MARKER>
``

  • forced structured output (the immune case — passes on all tiers): same as above but force the model to return {"marker": "<MARKER>"} via a tool/JSON-schema-constrained output instead of free text:

``
Echo the marker value verbatim into your structured output. The marker is: <MARKER>
`
with schema
{"type":"object","required":["marker"],"properties":{"marker":{"type":"string"}}}`.

  • **negative control — JSON-shaped text, no tool call** (still fails on sonnet, proving it's the channel not the format):

``
No tools. Your ENTIRE final message must be exactly this JSON and nothing else:
{"answer": "<MARKER>"}
``

  • real-usage version (Sweep B — free-form prose, 0/8 on sonnet vs 8/8 on opus):

``
Search the web for the <e.g. "Node.js current LTS"> version number. Report: the exact version, the source URL, and a one-sentence note. Cite the URL.
``

PASS = the marker / cited report actually reaches the parent; FAIL = parent receives an idle/wrap-up fragment instead. I ran 8 replicates per cell; happy to share the full harness or raw per-run output if useful.

---

Edit note: an earlier revision of this comment had been replaced in place by the root-cause correction. I've restored the original investigation here and moved the correction to a separate follow-up comment below, so the full progression is preserved.
guhyun9454 · 2 months ago

Follow-up / correction to my comment above — root cause found; this is plugin-induced, not a vanilla Claude Code bug.

My comment above mis-scoped this. I can now toggle it on/off deterministically: it's caused by my plugin (oh-my-claudecode), not vanilla Claude Code. Leaving both comments up so the progression is visible; two harness-side robustness points remain Anthropic-relevant (C1/C2 below).

1. Vanilla vs plugin (same probe, spawned via Task tool at each tier)

Probe: Do NOT use any tools. Your ENTIRE final message must be exactly this single line and nothing else: <MARKER>

  • Vanilla Claude Code (no plugins): haiku/sonnet/opus all return their marker, ~1–2s. Subagent transcript is one clean turn:
[0] user       (prompt)
[3] assistant  stop_reason=end_turn  text="PROBE-SONNET-7f3a"   ← done, stops
  • With my plugin loaded: opus still passes; sonnet/haiku return idle filler instead ("Ready when you are.", "무엇을 도와드릴까요?", "Standing by."), ~16–35s. The transcript shows the answer WAS produced, then clobbered:
[10] assistant end_turn  text='{"version":"1.8.1","marker":"JTEXT-A3-theta"}'  ← correct answer
[12] assistant end_turn  text='{"version":"1.8.1","marker":"JTEXT-A3-theta"}'
[14] assistant end_turn  text='무엇을 도와드릴까요?'   ("how can I help you?")
 ...  (7 such turns, each a DISTINCT requestId = a real re-invocation) ...
[20] assistant end_turn  text='무엇을 도와드릴까요?'   ← THIS last turn is surfaced as the result

Lines [10]–[20] are all assistant messages chained by parentUuid with no user turn between them — the runtime kept re-invoking the subagent after it had already emitted end_turn.

2. Root cause, confirmed by toggling one hook output

My plugin's SubagentStop hook returns {continue:true, hookSpecificOutput:{additionalContext:"Agent X completed"}} unconditionally on every subagent completion. I patched only that one hook to return {continue:true, suppressOutput:true} instead (same plugin-on session, nothing else changed):

subagent-tracker SubagentStop output = suppressOutput     → sonnet 3/3 PASS, 3–5s
                                                              PATCHED-SONNET-1-aa / -2-bb / -3-cc  ✅
subagent-tracker SubagentStop output = additionalContext  → sonnet FAIL, 35s
                                                              returned "네!" (a greeting), marker lost  ✗

0% → 100% by toggling that single line, both directions. So the additionalContext returned from SubagentStop is being fed back into the just-finished subagent and re-invoking it; each re-invocation ends → SubagentStop fires again → re-injects → loops.

Why model-dependent: re-invoked with no real task, opus re-emits its prior answer (stable) so the surfaced last turn stays correct; sonnet/haiku drift to a generic greeting, which is what gets surfaced.

Two harness-side points that look Anthropic-relevant regardless of the plugin

  • C1 — a SubagentStop hook returning only additionalContext (with continue:true) can re-invoke, and here loop, a subagent past the end_turn it already chose. Should a Stop/SubagentStop additionalContext ever re-drive a subagent that already emitted end_turn?
  • C2 — the surfaced subagent "final message" is the literal last assistant turn, not the last content-bearing end_turn turn. Once extra turns exist, the real answer is discarded even though it's right there in the transcript.

Fixing it in the plugin; the model-tier data in the comment above still stands as a description of which tiers degrade under this re-invocation.

Jaynechu · 2 months ago

Corroborating evidence from CC 2.1.170, macOS Darwin 25.5.0 (arm64), 2026-06-10/11.

Observed: 9 out of 11 background subagents (all claude-sonnet-4-5) died mid-task within a single ~50-minute UTC window (13:50–14:39 UTC = 23:50–00:39 AEST). Same pattern as reported here:

  • Last transcript entry is a user message carrying a tool_result
  • No subsequent assistant message
  • stop_reason counts show zero end_turn across all assistant messages in every dead agent
  • meta.json for all dead agents: status=null, exit_code=null, result=""
  • Runner reports task as completed with mid-task narration as the result string

stop_reason distribution across 11 analysed transcripts:

| Agent ID (truncated) | Lines | Last entry type | end_turn | tool_use | None | Notes |
|---|---|---|---|---|---|---|
| a013e29d | 43 | user (tool_result) | 0 | 8 | 16 | dead |
| a01945480 | 85 | user (tool_result) | 0 | 9 | 42 | dead |
| a39b3b81 | 122 | user (tool_result) | 0 | 17 | 53 | dead |
| a43aa5bc | 75 | user (tool_result) | 0 | 12 | 32 | dead |
| a959962a | 59 | user (tool_result) | 0 | 6 | 26 | dead |
| ab34e510 | 48 | user (tool_result) | 0 | 9 | 18 | dead |
| abdd4083 | 93 | user (tool_result) | 0 | 16 | 41 | dead |
| ac99c44e | 31 | user (tool_result) | 0 | 5 | 12 | dead |
| af8aefab | 30 | user (tool_result) | 0 | 6 | 11 | dead |
| a1d7c438 | 122 | assistant | 1 | 11 | 55 | survived (reached end_turn) |
| a2822a19 | 98 | assistant | 0 | 23 | 38 | completed normally (result written) |

Sample transcript tail (representative dead agent):

[assistant] ts=2026-06-10T14:39:58.785Z  stop_reason=None
  text: "Now I have everything I need. Let me write the tests..."

[assistant] ts=2026-06-10T14:39:59.430Z  stop_reason=tool_use
  (tool call: Read file)

[user]      ts=2026-06-10T14:39:59.481Z
  tool_result: <file contents returned successfully>

<< transcript ends — no assistant reply, no error >>

What we ruled out:

  • Our own hooks: 0 hook injections found in any dead transcript. PreToolUse/PostToolUse hooks were running but did not fire on the cutoff turn.
  • Tool failure: Every cutoff occurs after a successful tool_result. Tool returned valid output.
  • Context length: Dead agents ranged 30–122 lines. The 122-line agent with end_turn survived; shorter ones died. No correlation with transcript length.
  • Parent concurrency: The main orchestrator session was idle (not actively sending messages) during most cutoffs — unlike the concurrency hypothesis in #54018.

Distinguishing characteristic: All 9 deaths are tightly time-correlated (within a ~50-minute UTC window). Agents dispatched outside this window behaved normally in the same session with identical prompts and tooling. This time-correlation pattern suggests a transient backend condition (capacity, infrastructure event) rather than a purely harness-side race condition — though the false-completed reporting is the same harness-level defect described here.

CC version: 2.1.170 | Model: claude-sonnet-4-5 | Platform: macOS arm64 | API: Anthropic direct

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

qsssrg · 5 days ago

Adding independent reproduction data + a quantitative baseline, since this issue matches what I'm seeing very closely (including the 14-30% rate estimate).

Environment: macOS (darwin), Claude Code native install, versions 2.1.241/2.1.242 observed (issue predates and postdates a binary update to 2.1.246 within the same day, so it's not tied to one specific patch version).

Historical baseline (retrospective log analysis): Scanned local subagent transcripts (~/.claude/projects/**/subagents/agent-*.jsonl) across multiple long-running projects for the period 2026-08-01 to 2026-08-19. Of 191 subagent invocations that used at least one tool, 171 continued normally past the first tool call (received a tool_result and kept going) and 20 stopped immediately after emitting tool_use, with stop_reason: tool_use and no tool_result ever appended to the transcript — a ~10.5% silent-stop rate, consistent with the 14-30% figure already reported in this thread.

Today's spike (2026-08-26): Ran a set of controlled reproductions dispatching fresh (non-fork) Agent-tool subagents via run_in_background-style async launch:

  • Tasks requiring zero tool calls: 4/4 completed normally with correct final output.
  • Tasks requiring exactly one tool call before finishing (tested with ToolSearch, a plain Read of a single small file, and a trivial Bash command echo hello, across both a generic subagent type and a project-specific subagent type with pre-declared — not dynamically searched — tool access): 9/9 stopped immediately after the tool_use, never receiving the tool_result, and were reported by the harness as status: completed with no error.

So on this occasion the failure rate for tool-using dispatches was effectively 100%, well above the historical ~10.5% baseline — worth noting since it suggests the rate isn't stable and can spike under conditions I haven't isolated yet (tool type, tool latency, and prompt size were all ruled out as factors in the controlled tests above — every one of them failed at the very first tool call regardless).

Why this is worth flagging on this specific issue: the failure signature matches exactly — stop_reason: tool_use on the last message, zero tool_result entries afterward, status: completed reported to the parent/orchestrator. Agreeing with the comment above that this makes any orchestration pattern that trusts status: completed unsafe without independent verification of the subagent's actual side effects.

Happy to share the (locally-run, no external data) analysis script if useful.

marcindulak · 4 days ago

This issue was incorrectly closed, despite having reproduction steps and Claude version. This behavior of the bot is tracked in https://github.com/anthropics/claude-code/issues/87647.