/code-review regression since v2.1.235: background forked-skill execution — parent stalls on last angle, and ReportFindings UI is lost

Status Open
Maintainer reply None cached
Activity 5 comments · opened Aug 20, 2026

Summary

When running the /code-review skill (effort high) on the Fable model (claude-fable-5), the background review agent consistently stalls before producing its final report. It completes its per-dimension review angles, then ends its turn with a status like:

« Sept angles rendus. J'attends le dernier (efficiency) avant de dédupliquer et lancer la vérification. »

…and never resumes. The task-notification fires (agent stopped, no live background children), but the agent never dedupes findings, never runs its verification pass, and never emits the final report. The only workaround is to manually SendMessage the agent telling it to stop waiting and conclude, after which it finishes normally.

Reproduction

  1. Model: claude-fable-5 (Claude Code v2.1.236, macOS Darwin 25.5.0)
  2. In a repo with a substantial staged diff (~30 files), run /code-review high
  3. The review runs in the background, completes 7/8 angles, then stops with "waiting for the last angle" as its final text
  4. No further notification ever arrives; the report is never produced

Expected

The review agent should either be re-invoked when its last angle completes, or detect the missing/finished angle and proceed to dedup + verify + final report on its own.

Notes

  • The user reports this happens every time they use /code-review on the Fable model ("Ça fait ça à chaque fois que j'utilise le modèle Fable").
  • Resuming the agent with a SendMessage ("stop waiting, dedupe and report now") reliably unblocks it, so the state is intact — it just never wakes up on its own.
  • Subagent had consumed ~145k tokens / 18 tool uses at the time of the stall.

View original on GitHub ↗

5 Comments

LeFrenchie · 10 days ago

Follow-up: transcript analysis — no system error, it's a bookkeeping slip with no harness safety net

I extracted the subagent's JSONL transcript (~/.claude/projects/<project>/<session>/subagents/agent-<id>.jsonl). There is no error event anywhere — no failed tool_result, no API error. The stall is fully explained by the timeline:

| Time | Event |
|---|---|
| 12:01:16–12:02:15 | Review agent launches 8 finder subagents in the background |
| 12:03:43 | Agent notes: "Le finder « efficiency » a rendu 6 candidats. J'attends les 7 autres angles"efficiency is the FIRST angle to report back |
| 12:03:43 | Agent runs ToolSearch select:Monitor (loads the Monitor tool) but never uses it as a fallback |
| 12:04:32–12:08:34 | 7 task-notifications arrive, one per remaining finder. After each, the agent recounts correctly ("Deux angles rendus…", "Trois…", …, "Six angles rendus. Il reste B et efficiency.") |
| 12:08:37 | After the 7th and last notification, the agent ends its turn with: "Sept angles rendus. J'attends le dernier (efficiency)" — i.e. it waits for the angle it had already received first, 5 minutes earlier |
| 12:08:37 → 12:31:27 | Total silence. All 8 children are done, so no further task-notification can ever fire; the agent has no scheduled wakeup and no live children |
| 12:31:27 | Manual SendMessage ("stop waiting, dedupe and report") — agent resumes instantly and finishes normally in ~90s |

So two contributing factors:

  1. Model-side (Fable): the agent lost track of which angle had already reported — plausibly because the first result (efficiency) arrived through a different path than the later ones (it was known before any task-notification appeared in the transcript), so its "angles received" tally and the notification count diverged by one.
  2. Harness-side: when an agent ends its turn in a "waiting for X" state with zero live background children and no scheduled wakeup, nothing ever re-invokes it. A safety net here (e.g. re-invoke once with "no children are pending" when a turn ends waiting, or require a Monitor/wakeup when a turn's final text is a wait) would make this class of stall self-healing regardless of model bookkeeping.

State was fully intact — resume via SendMessage worked first try — which confirms this is purely a "nothing woke it up" problem.

LeFrenchie · 10 days ago

Reproduction context + raw log excerpt

Since a bare "/code-review high stalls" is unlikely to reproduce without the exact shape, here is the full context of the failing run:

Environment

  • Claude Code v2.1.236, macOS (Darwin 25.5.0), CLI entrypoint
  • Main session model: claude-fable-5; the review subagent and its finders also ran on claude-fable-5
  • Skill: built-in code-review, invoked as Skill(code-review, args: "high") from the main loop, which forks a background /code-review high agent

Shape that triggers it

  • The review agent launches 8 finder subagents via 8 separate background Agent calls (angles A/B/C, reuse, simplification, efficiency, altitude, conventions) against a ~2,750-line staged diff (30 files, mostly new PHP)
  • One finder ("efficiency") returns before any task-notification is emitted — its result was visible to the agent at 12:03:43, while the first task-notification only arrives at 12:04:32. The remaining 7 finders each produce a task-notification
  • Hypothesis: the early result and the notification stream are two different delivery paths, and the model's tally of "angles received" ends up off by one — it ends the run waiting for the angle that was delivered first

Raw JSONL excerpt (from ~/.claude/projects/<project>/subagents/agent-<id>.jsonl, sanitized to the relevant fields):

{"line": 49, "type": "assistant", "timestamp": "2026-08-20T12:03:43.225Z", "model": "claude-fable-5", "stop_reason": "tool_use", "text": "Le finder « efficiency » a rendu 6 candidats. J'attends les 7 autres angles avant de dédupliquer et lancer la vérification."}
{"line": 72, "type": "user", "timestamp": "2026-08-20T12:08:34.381Z", "origin": {"kind": "task-notification"}, "content": "[SYSTEM NOTIFICATION - NOT USER INPUT] ... (7th and last child-completion notification)"}
{"line": 74, "type": "assistant", "timestamp": "2026-08-20T12:08:37.952Z", "model": "claude-fable-5", "stop_reason": "end_turn", "text": "Sept angles rendus. J'attends le dernier (efficiency) avant de dédupliquer et lancer la vérification."}
{"line": 75, "type": "user", "timestamp": "2026-08-20T12:31:27.568Z", "origin": {"kind": "coordinator"}, "content": "The coordinator sent a message while you were working: Ton angle « efficiency » ne rendra rien de plus : ne l'attends plus. ..."}

Line 74 is the last event of the run until the manual coordinator message 23 minutes later: stop_reason: "end_turn", zero live children, no scheduled wakeup, and the final text is a wait for an already-delivered result. Nothing in the harness ever re-invokes it from that state.

LeFrenchie · 10 days ago

Root cause reframe: not Fable — the switch to background forked-skill execution (~v2.1.235)

Transcript archaeology across my sessions rules the model out in both directions:

  • Aug 8, session on claude-fable-5: ReportFindings succeeded 5× — reviews completed fine on Fable.
  • Aug 19–20, failing sessions: ran on claude-opus-5, no Fable involved.

The variable that flips on Aug 19 is the execution mode: until Aug 17 /code-review ran inline in the main agent (32 successful ReportFindings calls, last 2026-08-17T20:54Z); from Aug 19 (v2.1.235+) it runs as a background forked skill (forked-skill.marker.json, spawnDepth: 1). Two symptoms date from that switch:

  1. The stall reported here — the parent review agent ends its turn "waiting for the last angle" and is never re-invoked (matches my earlier follow-up: no error anywhere, just no wake-up).
  2. ReportFindings unavailable in the forkToolSearch("select:ReportFindings") returns empty inside the forked agent, so findings degrade to plain text ("The ReportFindings tool isn't available in this session…") and the sidebar findings UI never renders. The tool is exposed to the main agent in the same session. Reproduced on v2.1.235 and v2.1.237, two repos, effort medium, output style on/off, no allowedTools/disallowedTools config.

Retitled accordingly — the Fable attribution was correlation (I happened to be on Fable those days).

LeFrenchie · 10 days ago

Cross-references: this is a class of "forked/background agents get a pruned tool roster" bugs

Searching the tracker, both symptoms here are already reported elsewhere, which helps date and scope the regression:

The ReportFindings symptom (exact match):

  • #84093 — same bug, closed as completed on Aug 17 after a maintainer could not repro on 2.1.233. My transcript data above shows the regression starts with 2.1.235 (Aug 19) — i.e. the issue was closed against a build from before the regression window, one day before it (re)appeared. A commenter there (@yohanan) had already demonstrated the same parent/subagent asymmetry I reproduce: tool present with full schema in the main thread, absent from the subagent's roster in the same session.
  • #88190 — confirms the recurrence: --comment silently degrades to terminal printing when the forked agent lacks the posting tools, "repro on 2.1.237, after #84093 closed".

The stall symptom:

  • #86724 — "Nested-Agent orchestrator (e.g. built-in /code-review) reports status: completed after yielding to spawned children, before its assigned work is done" — the exact wake-up mechanics of the stall reported here.

Same class, other tools pruned from subagent rosters:

  • #84125 — LSP tool pruned from all subagent tool sets in interactive sessions (present in the parent).
  • #85230 — background subagents lose ListMcpResourcesTool/ReadMcpResourceTool.
  • #75559 — context:fork skill executions inherit the caller's StructuredOutput tool incorrectly; fork output silently lost.

Given the dated evidence (last inline success 2026-08-17T20:54Z on the pre-235 build; zero successes from 2.1.235 onward), #84093 likely deserves reopening or folding into this one.

LeFrenchie · 10 days ago

Additional data point: tool availability is only half the regression — the findings panel UI is gone even when ReportFindings succeeds

Tested on 2.1.235, interactive TUI session: I had the main agent run the review inline and call ReportFindings directly (bypassing the broken forked flow). The call succeeded ("1 finding reported") and the transcript rendered the compact inline block:

● Code review(medium · 1 finding)
  └ app/Support/ExistingKeywordsMap.php
    ● 15 [consistency] …

…but the full findings interface (sidebar + central detail panel) that used to open on /code-review before Aug 17 never rendered.

So two distinct layers regressed with the switch to background forked-skill execution:

  1. Tool availabilityReportFindings is not propagated to the fork (documented above).
  2. Panel rendering — even a successful main-agent call now only yields the compact inline block; the sidebar/panel UI appears to be wired to the (now-broken) skill flow rather than to the tool call. Possibly related to #73939 (desktop renders ReportFindings as raw JSON instead of the findings panel).

Env: v2.1.235, macOS Darwin 25.5.0, terminal (fullscreen TUI).