Auto-memory is sent to subagents despite docs stating it requires the `memory` field (34% of a small subagent's payload)

Status Open
Reported on v2.1.234
Maintainer reply None cached
Activity 0 comments · opened Aug 18, 2026

Summary

The subagent documentation states that a non-fork subagent starts with:

  • CLAUDE.md files (except Explore/Plan)
  • not auto memory, "unless memory field set"

I captured the raw HTTP request bodies and measured the opposite: auto-memory (MEMORY.md) is delivered to every subagent, bundled inside the # claudeMd context block, with no agent declaring a memory: field anywhere in the project.

On a small Haiku status-checking subagent this is 7,133 tokens — 34.0% of its entire 20,993-token first turn.

How it was measured

A local forwarding proxy set as ANTHROPIC_BASE_URL, logging request bodies verbatim and relaying to the API, so the parent turn genuinely runs and genuinely spawns a subagent. Exact token counts via POST /v1/messages/count_tokens on the captured payload. Transcript-based inspection cannot see this — injected context is assembled at request time and never written to the .jsonl.

What the subagent request actually contains

The subagent's messages[0] carries a text block of 53,310 bytes / 16,083 tokens, opening with <system-reminder>As you answer the user's questions, you can use the following context: and containing, in order:

# claudeMd
Contents of <project>/CLAUDE.md (project instructions, checked into the codebase):
  ...
Contents of <user>/memory/MEMORY.md (user's auto-memory, persists across conversations):
  ...
# currentDate

Split by count_tokens:

| component | tokens | bytes |
|---|---|---|
| whole inherited block | 16,083 | 53,310 |
| CLAUDE.md portion | 8,956 | 31,558 |
| MEMORY.md portion (auto-memory) | 7,133 | 21,752 |

The MEMORY.md portion is explicitly labelled (user's auto-memory, persists across conversations) in the payload itself, so it is unambiguously the auto-memory feature and not a file included via CLAUDE.md.

For context on the shape: the same subagent correctly does not receive the skills listing, the agent-type listing, MCP server instructions, SessionStart hook output, or 80 of the parent's 82 tool schemas. So subagent payload trimming clearly works in general — auto-memory just appears to ride along inside the CLAUDE.md block and escape it.

Expected vs actual

  • Expected (per docs): a subagent with no memory: field receives CLAUDE.md but not auto-memory.
  • Actual: it receives both, because auto-memory is nested inside the # claudeMd block rather than being a separately-gated section.

Why it matters

Subagents are a large share of token spend for agent-heavy workflows. Auto-memory grows monotonically with use, and it is content a status check or a grep sweep has no use for. There is also no per-agent way to opt out: no frontmatter key, settings key, env var or SDK AgentDefinition field controls CLAUDE.md/auto-memory inheritance (I probed 11 candidate key names empirically — all silently ignored, verified by diffing the resulting payloads against a control).

Either outcome is useful

  1. If this is a bug, gating auto-memory behind the documented memory: field would remove ~7k tokens from every subagent spawn in setups like mine.
  2. If it is intended, the docs are wrong and should say auto-memory is always inherited — and a per-agent opt-out would be a valuable addition, since Explore/Plan already prove the harness can skip this block.

Environment

  • Claude Code 2.1.234
  • macOS
  • Subagent: user-defined, model: haiku, small declared tool set, no memory: field

View original on GitHub ↗