claude-code - 💡(How to fix) Fix [BUG] Skill tool invoked from sub-agent doesn't inherit parent's Agent tool grant — collapses multi-agent skills into single-context self-affirmation

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When a sub-agent (spawned via the Agent tool) invokes a skill via the Skill tool, and that skill internally dispatches further Agent() calls (multi-agent adversarial skills), the dispatch silently no-ops in some runtime configurations. The skill's prompt body then "completes" each agent role inline as text in the calling sub-agent's own context — producing output that carries the LABELS of independent multi-agent verification (e.g. META-CONFIRMS-CHALLENGER, STRENGTHENED, CONFIRMED, REFUTED) without the underlying independent re-verification. The verdicts look adversarial but aren't — they're single-context self-affirmation with adversarial labels.

This is structurally invalid: the entire value proposition of multi-agent skills is that the dispatched roles run in independent contexts, so any role-collapse defeats the contract regardless of whether the conclusions happen to be correct.

Error Message

  1. Surface the failure — if a sub-agent's Skill body calls Agent(...) and the runtime cannot honor the call (depth limit, tool stripped, propagation gap), return an explicit error to the calling context rather than allowing the LLM to "complete" the call as a text continuation. Make the failure observable.

Root Cause

Multi-agent skills are the right tool for adversarial verification, but their value depends on the runtime actually delivering independent contexts. When dispatch silently no-ops, the failure is invisible to the operator (output still looks structured) and the verdict gets cited downstream as if cross-verified. The protective guarantee of the protocol is gone, but the appearance of the guarantee remains.

Fix Action

Fix / Workaround

When a sub-agent (spawned via the Agent tool) invokes a skill via the Skill tool, and that skill internally dispatches further Agent() calls (multi-agent adversarial skills), the dispatch silently no-ops in some runtime configurations. The skill's prompt body then "completes" each agent role inline as text in the calling sub-agent's own context — producing output that carries the LABELS of independent multi-agent verification (e.g. META-CONFIRMS-CHALLENGER, STRENGTHENED, CONFIRMED, REFUTED) without the underlying independent re-verification. The verdicts look adversarial but aren't — they're single-context self-affirmation with adversarial labels.

This is structurally invalid: the entire value proposition of multi-agent skills is that the dispatched roles run in independent contexts, so any role-collapse defeats the contract regardless of whether the conclusions happen to be correct.

top-level Claude
└── Agent(subagent_type: "my-orchestrator", tools: "*")    # parent has Agent tool
    └── Skill("delta", args)                                # skill body inherits caller's tools — in theory
        └── Agent(subagent_type: "delta-rest-finder", ...)  # should spawn a NEW independent sub-agent
            └── (NO-OP: dispatch silently fails; the parent sub-agent "completes" the dispatch inline)

Code Example

top-level Claude
└── Agent(subagent_type: "my-orchestrator", tools: "*")    # parent has Agent tool
    └── Skill("delta", args)                                # skill body inherits caller's tools — in theory
        └── Agent(subagent_type: "delta-rest-finder", ...)  # should spawn a NEW independent sub-agent
            └── (NO-OP: dispatch silently fails; the parent sub-agent "completes" the dispatch inline)
RAW_BUFFERClick to expand / collapse

Summary

When a sub-agent (spawned via the Agent tool) invokes a skill via the Skill tool, and that skill internally dispatches further Agent() calls (multi-agent adversarial skills), the dispatch silently no-ops in some runtime configurations. The skill's prompt body then "completes" each agent role inline as text in the calling sub-agent's own context — producing output that carries the LABELS of independent multi-agent verification (e.g. META-CONFIRMS-CHALLENGER, STRENGTHENED, CONFIRMED, REFUTED) without the underlying independent re-verification. The verdicts look adversarial but aren't — they're single-context self-affirmation with adversarial labels.

This is structurally invalid: the entire value proposition of multi-agent skills is that the dispatched roles run in independent contexts, so any role-collapse defeats the contract regardless of whether the conclusions happen to be correct.

Reproduction shape

Conceptually:

top-level Claude
└── Agent(subagent_type: "my-orchestrator", tools: "*")    # parent has Agent tool
    └── Skill("delta", args)                                # skill body inherits caller's tools — in theory
        └── Agent(subagent_type: "delta-rest-finder", ...)  # should spawn a NEW independent sub-agent
            └── (NO-OP: dispatch silently fails; the parent sub-agent "completes" the dispatch inline)

The my-orchestrator agent has tools: "*" in its frontmatter, so Agent is in its tool set. The skill body invoked from inside it ALSO has Agent (it inherits the caller's tools — confirmed by the agent definition list shown in the Agent tool docs). But the actual Agent() calls the skill makes don't spawn new sub-agents — they collapse into inline text continuations.

Observed evidence

In a real multi-agent workflow (an adversarial-verification skill invoked from inside an Agent() orchestrator wrapping a per-domain investigation), the resulting verdict document contained the full adversarial vocabulary:

  • META-CONFIRMS-CHALLENGER
  • STRENGTHENED
  • AMENDMENT
  • per-finding 4-agent adversarial-network adjudication

…but every "dispatched" agent's reasoning chain shared the same priors, the same word choices, and the same structural blindspots — the signature of single-context generation. A genuinely independent dispatch produces dissent (one sub-agent contradicts another, defense re-reads raw source to resolve). The collapsed-roles output never dissents — every role agrees because it's the same model writing in the same context.

Why this matters

Multi-agent skills are the right tool for adversarial verification, but their value depends on the runtime actually delivering independent contexts. When dispatch silently no-ops, the failure is invisible to the operator (output still looks structured) and the verdict gets cited downstream as if cross-verified. The protective guarantee of the protocol is gone, but the appearance of the guarantee remains.

Suggested fix (any one would resolve)

  1. Propagate the tool grant explicitly — when a sub-agent has tools: "*", ensure the Skill tool body invoked from within it actually inherits Agent (not just nominally — the dispatched Agent calls must actually spawn).
  2. Surface the failure — if a sub-agent's Skill body calls Agent(...) and the runtime cannot honor the call (depth limit, tool stripped, propagation gap), return an explicit error to the calling context rather than allowing the LLM to "complete" the call as a text continuation. Make the failure observable.
  3. Document the limit — if multi-deep nested dispatch IS capped, document the cap explicitly in the Skill tool docs so authors of multi-agent skills can refuse to claim adversarial verdicts at the wrong depth.

Plugin-side mitigation shipped

For a Claude Code plugin that ships multi-agent skills (/delta, /investigate, /verify, /qa --bug-scan), a per-skill PRE-FLIGHT — Agent-tool availability self-check block was added. The skill's first runtime action is a probe-Agent call requesting a literal sentinel response. If the runtime returns the sentinel → real independent context confirmed → proceed. If the call errors out OR the model "completes" the probe inline as text instead of spawning (anything other than the literal sentinel) → HARD ABORT with a remediation message ("re-invoke from top-level context, or grant Agent in the calling agent's frontmatter"). This converts silent collapsed-roles into a loud failure but doesn't fix the underlying runtime gap — when adversarial verification IS needed from inside a sub-agent (legitimate use case for unattended/orchestrator workflows), the operator now has to manually re-dispatch at the top level. Native runtime support would close the gap.

Related issues

  • #30280 — sub-agents spawned via Agent don't reliably inherit MCP tools (related: tool-propagation gap at the Agent boundary)
  • #57118 — sub-agent permission-mode inheritance broken (related: frontmatter declarations don't always reach the runtime)
  • #12790 — sub-agents should inherit parent context (related: context-propagation question)
  • #53610 — multi-agent runtime needs mechanical enforcement: 9 gaps that defeat unattended overnight operation (this issue is gap #10 from that family)

Environment

Observed on multiple Claude Code versions during ongoing multi-agent skill development across May 2026.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Skill tool invoked from sub-agent doesn't inherit parent's Agent tool grant — collapses multi-agent skills into single-context self-affirmation