Memory explosion (400MB → 14GB) when subagent invokes Skill tool - WebKit Malloc leak
Bug Report: Memory explosion (400MB → 14GB) when subagent invokes Skill tool
Summary
When a subagent (spawned via Task tool) attempts to invoke the Skill tool to call another agent, Claude Code's memory usage explodes from ~400MB to 14GB+, causing the application to hang.
Environment
- Claude Code version: 2.1.25
- OS: macOS 26.3 (Darwin 25.3.0)
- Architecture: ARM64 (Apple Silicon)
- MCP Servers: Playwright, backlog.md, shadcn-ui, IDE
Steps to Reproduce
- Create a custom agent
task-validatorthat has access to theSkilltool - Create a custom agent
bug-reporter(any configuration) - Create a skill
/report-bugthat invokes thebug-reporteragent - In the
task-validatoragent's system prompt, include instructions like "If you find bugs, call the bug-reporter agent" - Launch Claude Code and spawn
task-validatorvia Task tool - Give task-validator a prompt that causes it to try invoking
Skill("report-bug")orSkill("bug-reporter")
Minimal reproduction:
User: /validate-task Your task is to spawn a bug-reporter agent with prompt: "test"
When task-validator attempts to call the Skill tool to invoke bug-reporter, memory explodes.
Expected Behavior
- Subagent should either successfully invoke the skill, or
- Gracefully fail with an error message if nested skill invocation is not supported
Actual Behavior
- Memory usage jumps from ~400MB to 14GB+ within seconds
- Claude Code becomes unresponsive
- The process must be force-killed
Memory Analysis
Using vmmap before and during the spike:
Before Spike
Physical footprint: 400.0M
Physical footprint (peak): 697.1M
WebKit Malloc: 9.1G virtual, 826.8M resident, 58 regions
During Spike
Physical footprint: 14.1G
Physical footprint (peak): 14.1G
WebKit Malloc: 20.9G virtual, 11.6G resident, 487 regions
Key Finding: WebKit Malloc Explosion
| Metric | Before | During Spike | Change |
|--------|--------|--------------|--------|
| Virtual Size | 9.1G | 20.9G | +11.8G |
| Resident | 826.8M | 11.6G | +10.8G |
| Dirty | 256.8M | 11.0G | +10.7G |
| Region Count | 58 | 487 | 8x more |
The memory explosion is in WebKit Malloc, suggesting the issue is in the JavaScript runtime (Bun uses JavaScriptCore/WebKit). This could be:
- Recursive/exponential copying of agent context
- Unbounded string concatenation during skill resolution
- Circular reference causing infinite serialization
Investigation Notes
During debugging, we discovered:
- The spike does NOT occur when the main agent invokes Skill directly
- The spike DOES occur when a subagent (via Task tool) tries to invoke Skill
- The spike occurs regardless of bug-reporter's tool list size - even with minimal tools (just
Read), the spike still happens - The spike occurs regardless of bug-reporter's description length
- The spike does NOT occur when task-validator tries to spawn
general-purposeagent
This suggests the issue is specifically triggered when:
- A Task-spawned subagent
- Attempts to invoke a Skill
- That references a custom user-defined agent
Workaround
Avoid having subagents invoke Skills that spawn other agents. Instead:
- Have subagents return findings to the main agent
- Let the main agent spawn additional agents as needed (flat architecture instead of nested)
Files Attached
/private/tmp/vmmap_before_spike.txt- vmmap output before spike/private/tmp/vmmap_during_spike.txt- vmmap output during spike (14GB)
Additional Context
The task-validator agent configuration includes Skill in its tools list, and its system prompt mentions "call the bug-reporter agent" when bugs are found. The agent correctly attempts to use the Skill tool, but the system fails to handle this gracefully.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗