Memory explosion (400MB → 14GB) when subagent invokes Skill tool - WebKit Malloc leak

Resolved 💬 4 comments Opened Jan 30, 2026 by szym0nDr4g Closed Feb 28, 2026

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

  1. Create a custom agent task-validator that has access to the Skill tool
  2. Create a custom agent bug-reporter (any configuration)
  3. Create a skill /report-bug that invokes the bug-reporter agent
  4. In the task-validator agent's system prompt, include instructions like "If you find bugs, call the bug-reporter agent"
  5. Launch Claude Code and spawn task-validator via Task tool
  6. Give task-validator a prompt that causes it to try invoking Skill("report-bug") or Skill("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:

  1. The spike does NOT occur when the main agent invokes Skill directly
  2. The spike DOES occur when a subagent (via Task tool) tries to invoke Skill
  3. The spike occurs regardless of bug-reporter's tool list size - even with minimal tools (just Read), the spike still happens
  4. The spike occurs regardless of bug-reporter's description length
  5. The spike does NOT occur when task-validator tries to spawn general-purpose agent

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.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗