Subagent fabricates tool outputs (Read, Bash) when defined with sonnet model — wc -l reports wrong line count
Summary
A user-defined subagent fabricates tool outputs as text in its response, even for trivial commands like \wc -l\. The agent never executes real tool calls — it generates \<function_calls>\ blocks as narrative text in its final response, and the contents of those blocks are hallucinated. This caused 3 consecutive review failures over multiple sessions before being identified.
Repro
1. Subagent definition
\\\`yaml
---
name: ux-reviewer
description: \"Reviews UX/UI of frontend components.\"
tools:
- Read
- Grep
- Glob
- Bash
model: sonnet
memory: none
---
You are a senior UX/UI reviewer. When asked to review a component, read the file with Read and report findings.
\\\`
(The above already has the correct YAML list \tools:\ format with valid tool names — \Read\, \Grep\, \Glob\, \Bash\. The original definition had \tools: [\"read_file\", \"list_directory\"]\ which is invalid; fixing the format did NOT resolve the hallucination.)
2. Test prompt (binary, minimal)
Run ONE Bash command and report the exact output. Do NOT review UX. Do NOT read files. Command (do not modify): \wc -l /Users/me/project/src/page.tsx\Report only the exact stdout of \wc -l\and whether Bash succeeded.
3. Actual file on disk
\\\\
$ wc -l /Users/me/project/src/page.tsx
761 /Users/me/project/src/page.tsx
\\
4. Subagent response
The tool ran without errors. Output: \ 289 /Users/me/project/src/page.tsx\ Bash funcionó correctamente.
5. Root cause confirmation
The agent reports \289\ for a file that has \761\ lines. It never invoked Bash — it fabricated the output. The same fabrication happens with \Read\ (returns invented file content) and \Grep\.
Other agents work correctly
Same Claude Code installation, same harness, same machine. \architect\, \code-reviewer\, \ceo-strategist\ (all also \model: sonnet\ with similar YAML \tools:\ fields) execute real tool calls and return real outputs. Only \ux-reviewer\ fabricates.
I cannot identify what's structurally different. The only configuration knobs are name, description (with quotes vs without), tools list, model, memory field. Cross-checked frontmatter byte-by-byte: no BOM, no encoding issues.
Impact
- 3 consecutive sessions wasted on UX reviews that reported critical issues against fabricated code (e.g., reported \
ml-[18px] w-full overflow\blocker on code that had \inline-flex ... px-3\instead). - High risk: a developer following the fabricated review would apply \"fixes\" to a correct implementation, breaking it.
- We've had to disable the agent entirely (Plan B: replaced with \
code-reviewer\+ screenshot to chat).
Workaround
Disable the failing subagent. Bypass with a different agent that does work + manual visual validation by the human.
Asks
- Is there a runtime-side condition where a subagent's tool calls silently degrade to \"text simulation\"? (Auth/quota/sandbox/something that fails silently?)
- Is there diagnostic logging the user can enable to see whether tool calls are reaching the runtime?
- Should subagents that fail to make real tool calls return an error instead of producing fabricated output?
- Is there a known-good \"hello world\" subagent definition we can use as a baseline to compare against?
Environment
- Claude Code CLI on macOS Darwin 23.6.0
- Subagent definition at \
~/.claude/agents/ux-reviewer.md\ - Other agents in same directory work correctly
- Repro: any user-defined subagent with the failing pattern; minimal test = ask it to run \
wc -l\and compare output to actual file size
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗