Forked skill execution double-orchestrates: agent notifications route to parent while fork runs the pipeline; Skill re-invocation re-executes from scratch

Status Open
Reported on v2.1.251
Maintainer reply None cached
Activity 0 comments · opened Aug 31, 2026

Environment

  • Claude Code version: 2.1.251
  • Platform: macOS (darwin 25.6.0), zsh
  • Model: claude-fable-5

Summary

A skill that runs as a forked execution (/code-review at a high effort level) ended up being orchestrated twice in parallel: the fork ran the whole review pipeline itself, while the task-notifications from the background agents it spawned were also delivered to the parent session, which had no way to see the fork's progress and therefore ran its own dedup/verification pass over the same results. Additionally, re-invoking the Skill tool later in the session (to recover the skill instructions lost to context compaction) did not reload instructions — it re-executed the skill from scratch in a new fork, relaunching all 10 finder subagents (~700k duplicated subagent tokens).

What happened (timeline)

  1. User ran /code-review <level> --comment PR#<n> on a large PR. The skill executed as a fork; its stdout ("All 10 finder angles are running in the background…") returned to the terminal, and the fork kept running (~23 min total).
  2. The 10 finder subagents' <task-notification> events were delivered to the parent session as they completed — so the parent proceeded to the skill's next phase (dedup + verification) using those results.
  3. Meanwhile the fork (which apparently also received/held the results) independently completed the full pipeline — dedup, verification, and posting the review comments to the PR.
  4. The parent could not inspect the fork: ListAgents showed it as a running subagent, but TaskOutput on it returned No task found with ID: …. There was no signal telling the parent "a fork is already orchestrating this; stand by."
  5. Mid-run, after context compaction removed the skill instructions, the parent re-invoked Skill("code-review", args=…) expecting an instruction reload. The invocation forked again and relaunched all 10 finder angles as duplicate background agents.
  6. Minor, same run: the effort-level argument had a typo (xghigh); the skill silently fell back to the last-used level (high) instead of erroring or asking, so the review ran at a lower level than the user intended.

Expected

  • One orchestrator per skill run: either the fork owns the run (and the parent gets no per-agent notifications, just the fork's final result), or the parent owns it (and the fork doesn't independently complete the pipeline).
  • A way for the parent to see/inspect a running skill fork (TaskOutput accepting the id that ListAgents reports, or a status line in the notification).
  • Skill re-invocation mid-run should not silently re-execute a pipeline already in flight — or at least the tool result should warn that a fork for the same skill is still running.
  • An invalid effort-level argument should surface as an error rather than silently downgrading.

Actual

Two full review pipelines ran (double token spend); the parent and fork raced to produce/post results; a Skill re-invocation duplicated 10 background agents; the level typo silently downgraded the run.

Repro

  1. Run a forked-execution skill that spawns background agents (e.g. /code-review xhigh --comment <PR>) on a diff large enough that the run spans a context compaction.
  2. Observe the finder task-notifications arriving in the parent session while the fork is still running.
  3. Re-invoke the Skill tool from the parent after compaction; observe a fresh duplicate set of background agents spawn.

View original on GitHub ↗