[BUG] Workflow agent() silently removes the Agent tool from custom agent types that declare it (affects the official claude-security plugin)
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?
An agent launched by a workflow script with agent(prompt, { agentType }) never receives the Agent tool, even when that agent type's tools: frontmatter lists Agent or Agent(<type>) explicitly. The same agent definition spawned through the Agent tool does receive it, at the same spawn depth.
The removal is silent. Nothing in the agent's transcript or the workflow log says a declared tool was dropped, so the agent just never delegates, and its prompt's delegation instructions quietly become impossible to follow.
This affects the official claude-security plugin (0.12.0, claude-plugins-official):
agents/scan-researcher.mdandagents/scan-verifier.mdboth declaretools: Read, Glob, Grep, Bash, Agent(claude-security:explore).scan-researcher's prompt tells it to "dispatchclaude-security:explorewith the question and build on what it returns".- Both agents are launched only by
workflows/scan.jsthroughagent({ agentType }), so during a scan they can never dispatchexplore. They do all exploration in their own context instead.
In claude-security plugin, where explore is responsible for resolving symbols defined in other repositories, this went unnoticed. The researchers and verifiers fell back to broad grep -r over sibling checkouts in their own context: about 45% of the run's tool calls and nearly half of all agent wall time.
What we found in the 2.1.296 and 2.1.299 bundles: the built-in workflow subagent definition (workflow-subagent) carries disallowedTools: [SendUserMessage, Agent, Workflow]. For agent({ agentType }), the custom definition's disallowedTools are concatenated with that list, so Agent is removed from every workflow agent whatever its tools: says. It is not the nesting depth limit: CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH is unset, the effective limit is 3, and workflow agents run at depth 1.
None of this is documented. The sub-agents docs say that listing Agent in a subagent definition's tools "lets that subagent spawn subagents of its own while the depth limit allows it". The workflows docs and the workflow-authoring reference describe agentType as "resolved from the same registry as the Agent tool" and say nothing about tools being removed.
What Should Happen?
One of the following, in order of preference:
- A workflow agent whose agent type explicitly lists
Agent/Agent(...)intools:receives it, subject to the normal depth limit. Or, if nesting from workflows must stay opt-in, an explicit per-call opt-in such asagent(prompt, { agentType, allowAgentTool: true })(name illustrative). Agents spawned this way could count toward the run's agent cap and concurrency limit, so the script's own accounting still holds. - If the restriction is intentional, document it in the workflows docs and in the
agentTypedescription of the workflow-authoring reference. Also emit a visible warning (workflow log and agent transcript) when a declaredAgententry is withheld, instead of dropping it silently.
Either way, the official claude-security plugin should not ship agents whose declared tools and prompt instructions cannot work in the only context they are launched from.
Error Messages/Logs
Steps to Reproduce
- Create
.claude/agents/delegator.md:
``markdown``
---
name: delegator
description: Test agent that may delegate to other agents.
tools: Read, Agent
---
Report the exact names of every tool available to you, comma-separated, and nothing else.
- In a session, ask Claude to spawn the
delegatoragent with the Agent tool.
Result: Read, Agent, SubagentHandback (the transcript confirms it).
- In the same session, run a workflow:
``js``
export const meta = { name: 'agent-tool-probe', description: 'List a workflow agent tools' }
return await agent('List your tools.', { agentType: 'delegator' })
Result: Read. The transcript under ~/.claude/projects/<project>/<session>/subagents/workflows/<runId>/ confirms the tool list.
- Optional, real-world case: install
claude-securityfrom claude-plugins-official, run a codebase scan, and inspect the tool lists of thescan-researcher/scan-verifierworkflow agents.
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.299 (Claude Code)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_