Subagent with `tools: []` is listed to its parent as "(Tools: All tools)"

Status Open
Reported on v2.1.219
Maintainer reply None cached
Activity 1 comment · opened Jul 30, 2026

Summary

A subagent defined with tools: [] is advertised to its parent agent as (Tools: All tools) in the available-agent-types listing. The label is the exact opposite of the truth: the agent is spawned with an empty tool set.

Version

Claude Code 2.1.219 (macOS desktop app).

Reproduction

  1. Create ~/.claude/agents/file-inspector.md:
---
name: file-inspector
description: Inspects files and reports their properties.
tools: []
model: claude-opus-5
---

You inspect files and report their properties.
  1. Start a session and look at the available agent types listed to the main agent.

Expected: something indicating no tools — e.g. (Tools: None).

Actual: - file-inspector: Inspects files and reports their properties. (Tools: All tools)

Cause

The listing label is chosen with a truthy-length check on the resolved tools array: a non-empty list is joined by name, otherwise (with no disallowedTools) it falls through to the literal string "All tools". An empty array therefore takes the same branch as an unspecified one, even though the two mean opposite things.

The spawn path itself is correct and unaffected — it accepts an empty tool set, and the zero-tool spawn refusal only fires when declared entries resolve to nothing (unrecognized, unavailable to subagents, or matching no tool in the session), which an empty list never triggers. So only the label is wrong.

Impact

The listing is what an orchestrating agent reads when choosing where to delegate. An agent labelled "All tools" will be handed file or command work it cannot perform. In our testing, such a subagent does not fail loudly — with 8 spawns against real files under an ordinary task-first brief, every one produced an imitation Bash call in prose and 7 of 8 also produced imagined command output (a false No such file or directory for files that existed), with zero structured tool_use events in any transcript. The misleading label makes that failure mode harder to anticipate.

Suggested fix

Distinguish "empty list" from "not specified" when rendering the label — report None (or similar) when tools is present but empty.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗