[BUG] /context undercounts the active --agent persona + agent-memory injected into system (breakdown identical to a bare session)

Open 💬 0 comments Opened Jun 29, 2026 by petaxie

Summary

/context (and /context all) report a token breakdown whose "System prompt" line is byte-identical for a claude --agent <role> session and a bare claude session — even though, for an --agent session, the agent's persona definition and its agent-memory (~/.claude/agent-memory/<role>/MEMORY.md) are injected into the request's system parameter.

No /context category reflects this injection (Custom agents counts only the agent-picker definitions; Memory files counts only CLAUDE.md + project memory). As a result /context is misleading for verifying whether an agent's persona/memory actually loaded, and it under-reports real context usage for agent sessions.

Environment

  • Claude Code 2.1.195
  • macOS 26.5.1 (arm64)
  • Subscription auth, model claude-opus-4-8

Repro

  1. Create a throwaway agent memtest with a memory file containing a distinctive marker, e.g. ~/.claude/agent-memory/memtest/MEMORY.md containing MARKER_ZZZ plus a few KB of filler. Add a matching agent definition (~/.claude/agents/memtest.md with memory: user).
  2. claude --agent memtest/context all → note System prompt tokens.
  3. claude (bare, same dir) → /context all → note System prompt tokens.
  4. Observed: the two breakdowns are identical (in our case both System prompt: 4.7k, and every other static category equal), despite the agent carrying a multi-KB persona + memory.
  5. Ground-truth via wire capture — point ANTHROPIC_BASE_URL at a tiny local logger and compare the real system field:
// cap.js — log-only: captures the /v1/messages request body, returns a dummy error.
// The call will fail (dummy 500); that's fine — the request body is already captured.
const http = require('http'), fs = require('fs');
http.createServer((req, res) => {
  const c = [];
  req.on('data', d => c.push(d));
  req.on('end', () => {
    if (req.url.includes('/v1/messages')) {
      try {
        const j = JSON.parse(Buffer.concat(c).toString());
        const sys = typeof j.system === 'string'
          ? j.system : (j.system || []).map(b => b.text || '').join('\n');
        fs.appendFileSync('/tmp/sys.txt',
          `system_len=${sys.length}  hasMARKER=${sys.includes('MARKER_ZZZ')}\n`);
      } catch (e) {}
    }
    res.writeHead(500); res.end('captured');
  });
}).listen(8787, () => console.log('on :8787'));
node cap.js &
ANTHROPIC_BASE_URL=http://localhost:8787 claude --agent memtest -p hi   # capture #1
ANTHROPIC_BASE_URL=http://localhost:8787 claude -p hi                   # capture #2
cat /tmp/sys.txt

The agent session's system is substantially larger and contains MARKER_ZZZ; the bare session's does not.

Evidence (real system param, captured at the wire)

| session | real system size | contains persona+memory? | /context "System prompt" |
|---|---|---|---|
| bare claude | ~7,899 chars | no | 4.7k |
| --agent (-p) | ~20,917 chars | yes | 4.7k |
| --agent (interactive) | ~26,571 chars | yes | 4.7k |

The ~13–19k-char delta (persona body + agent-memory) is present in the actual request system but invisible in /context.

Expected

/context should attribute the injected persona definition + agent-memory to a category (either fold it into "System prompt", or add a dedicated "Agent / agent memory" line), so the breakdown matches what is actually sent.

Actual

The agent injection is uncounted; an --agent session's /context breakdown is identical to a bare session's.

Impact

For workflows that rely on --agent personas with persistent agent-memory, /context is the natural way to confirm "did my agent context load." Because it under-reports, we spent multiple days with the false belief that interactive --agent sessions weren't loading agent-memory at all (they are — it's in system). It also understates real context-budget consumption for agent sessions on long conversations.

Notes

  • The "System prompt" figure appears to be a static value that doesn't include dynamically-injected agent content.
  • There is currently no built-in way to inspect the real outgoing system: the session transcript (.jsonl) stores no API-system record (only local_command stdout etc.), and --debug / --debug-file log streaming/model metadata but not the request body. A debug option to dump the (redacted) outgoing request would make this class of issue self-diagnosable.

View original on GitHub ↗