advisor() tool inflates reported input tokens by forwarding full transcript, triggering premature auto-compaction on extended context models
Summary
When advisor() is called, the full conversation transcript is forwarded to a second model (currently claude-opus-4-7). The token usage from both the main executor and the advisor sub-inference are summed in the top-level usage fields. If Claude Code's auto-compaction logic uses these summed totals, the advisor call effectively doubles the apparent context usage, triggering compaction when the main model's actual context is only ~50% full.
Reproduction
- Start a Claude Code session with
claude-opus-4-6[1m](1M context) - Work normally until the main context reaches ~400K-500K input tokens
- Call
advisor() - Observe: auto-compaction fires immediately after the advisor call returns
Evidence from session JSONL
Session ID: c3a29188-290f-4af2-be48-8f6fb6929111
Model: claude-opus-4-6[1m]
Project: CriticalSkip
Token progression at the compaction boundary
| JSONL line | Total reported input | Notes |
|-----------|---------------------|-------|
| 1972 | 513,354 | Normal turn, main context only |
| 1979 | 1,028,789 | advisor() called — reported total doubled |
| 1994 | — | "Conversation compacted" system message |
| 2012 | 35,693 | Post-compaction context (wiped to ~36K) |
Iteration breakdown for the advisor turn (line 1979)
{
"input_tokens": 4,
"cache_creation_input_tokens": 1731,
"cache_read_input_tokens": 1027054,
"iterations": [
{
"type": "message",
"input_tokens": 3,
"cache_read_input_tokens": 513353,
"cache_creation_input_tokens": 348,
"output_tokens": 35
},
{
"type": "advisor_message",
"model": "claude-opus-4-7",
"input_tokens": 701354,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"output_tokens": 5672
},
{
"type": "message",
"input_tokens": 1,
"cache_read_input_tokens": 513701,
"cache_creation_input_tokens": 1383,
"output_tokens": 544
}
]
}
Key observation: The main model's actual context was 513-515K tokens (iterations 1 and 3). The advisor sub-inference consumed 701K tokens (iteration 2 — the full transcript forwarded uncached). The top-level cache_read_input_tokens reports 1,027,054 — the sum across all iterations — making it appear the context is at 1M when only half is actually used by the executor.
The math
- Main executor context: ~513K tokens (well within 1M window)
- Advisor receives full transcript: ~701K tokens (separate model, separate inference)
- Reported total: ~1,028K tokens (sum of both)
- Auto-compaction threshold: likely ~95% of 1M ≈ 950K
- Result: compaction fires at 513K actual context because 1,028K > threshold
Expected behavior
Advisor sub-inference tokens should not count toward the auto-compaction threshold. The advisor is a separate model call with its own context window. The executor's context at 513K is well within the 1M budget and should not trigger compaction.
Actual behavior
The summed total (executor + advisor) exceeds the compaction threshold, and auto-compaction fires immediately. The session loses ~500K tokens of working context unnecessarily.
Impact
- On extended context models (1M): Any advisor call past ~400K main context will trigger compaction, since
400K main + ~550K advisor = ~950K ≈ threshold - Effectively halves usable context: The 1M context window becomes ~400-450K when advisor is used, because the remaining ~550K is reserved for the advisor's copy of the transcript
- Inconsistent: Early-session advisor calls work fine. Late-session calls compact. Users experience this as random/intermittent compaction
- Counterproductive: The advisor is most valuable late in a session (complex decisions with full context), but that's exactly when it triggers compaction and destroys the context it was supposed to help with
Workaround
Setting CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=98 and/or using a PreCompact hook that blocks auto-compaction:
{
"hooks": {
"PreCompact": [{
"hooks": [{
"type": "command",
"command": "bash -c 'INPUT=$(cat); TRIGGER=$(echo \"$INPUT\" | python3 -c \"import sys,json; print(json.load(sys.stdin).get(\\\"trigger\\\",\\\"unknown\\\"))\" 2>/dev/null); [ \"$TRIGGER\" = \"auto\" ] && echo \"{\\\"decision\\\":\\\"block\\\"}\" && exit 2; exit 0'",
"timeout": 3
}]
}]
}
}
This blocks all auto-compaction and relies on manual /compact. Not ideal but prevents the advisor from triggering premature compaction.
Related issues
- #34332 — Opus 4.6 (1M context): autocompact triggers at ~76K tokens
- #50204 — Auto-compact triggers prematurely with extended context models
- #15377 — Conversations compacting prematurely at ~65% token capacity
- #49994 — Sessions using advisor() become permanently unrecoverable (expired encrypted payloads)
- #42647 — High token burn due to redundant context resubmission in compaction pipeline
Suggested fix
When calculating context usage for the auto-compaction threshold, use only the executor's input_tokens + cache_read_input_tokens + cache_creation_input_tokens from type: "message" iterations. Exclude type: "advisor_message" iterations from the calculation. The advisor tool documentation already states that "top-level max_tokens applies to executor output only" and that "the advisor's tokens do not draw from any task budget applied to the executor" — the compaction logic should follow the same principle.
Environment
- Claude Code version: 2.1.111
- Model: claude-opus-4-6[1m]
- Advisor model: claude-opus-4-7
- Platform: Windows 10 Pro
- Settings:
advisorModel: "opus",effortLevel: "medium"
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Ditto. I have this exact same issue and even filed an issue (#55702) that turned out to be a duplicate of this one. I'm using Linux with Opus 4.6 [1M] as my main model and Opus 4.7 as the advisor model.
I have auto-compaction disabled. My workaround has been to
/rewindto right before the advisor call and ask Claude to generate a session handoff file with the next instruction saying to call the advisor. Then I/clearand run@SESSION_HANDOFF.md.This bug still occurs on v2.1.126.
Yesterday I started a new session on v2.1.126 with Opus 4.7 and gave it a single complex prompt using a session handoff file. The context window limit was reached before Claude could completely finish my prompt, and it happened because Claude invoked the advisor at around 480K context tokens which triggered this bug; thus, the context size doubled and my prompt died due to hitting the context limit.
Since my session was literally just a single prompt, I couldn't
/rewindback before the advisor call to salvage my session.Please update the tags to specify that this bug isn't limited to Windows, as I experience this bug in Linux.
The bug is 100% reproducible. It really diminishes the value of the advisor feature.
This issue still occurs on v2.1.140. Please, kindly prioritize fixing it as it significantly limits the advisor's potential.
still happening...
Still happens on v2.1.148, and it is still 100% reproducible. I even got a weird one today where 3 back-to-back Advisor calls caused my session to hit the 1M context limit even though I started with 25% of the context window full. So multiple consecutive Advisor calls can bust a session even when you're well below 50% of context filled.
More info — independently reproduced on
claude-opus-4-7[1m], with two facets worth adding.Hit this on Claude Code 2.1.150 / macOS /
claude-opus-4-7[1m]. A singleadvisor()call took the statusline from ~406K →1170k/1000k (117%),+782kin one turn. Iteration-level data confirms your diagnosis exactly, and adds (1) a timeout-driven ×3 and (2) confirmation it's display-only — the prompt cache and the executor's real context are untouched (the #17959 symptom).Same accounting, confirmed
The advisor turn's
usage:381449 + 387405 + 387405 = 1156259= the top-levelcache_readexactly. So the top-levelcache_readis Σcache_readover the executor (type:"message") sub-iterations, and eachadvisor()invocation adds one executor re-read of the same cached context. General rule:The advisor's transcript forward is the separate
advisor_message(input_tokens=395834, uncached) and is not in the top-levelcache_read. Control from the same session — a successful, single advisor call on a ~113K context reportedcache_read = 113080 + 114484 = 227564→ ×2, matching your 513K→1028K.Facet 1 —
execution_time_exceeded→ auto-retry → ×3 (not ×2)My turn has two
server_tool_use{name:"advisor"}blocks. The first returned:…on a ~385K transcript (the reviewer can't finish within its server-side budget), so it auto-retried. Two invocations → three executor
messageiterations → ×3 (1,156,259), not ×2. The timed-out attempt left no billedadvisor_messageiteration but cost ~8 min wall-clock and forced the extra re-read at iteration[1]. So on large contexts the inflation multiplier can exceed 2.Facet 2 — the inflation is display-only; cache and real context are untouched
The 117% does not reflect real context growth. The next turn read
cache_read=387405withcache_creation=7167— a normal incremental, so the prompt cache stayed fully intact and the executor's real context never left ~385K. The inflated figure is a pure accounting artifact of the summedcache_read, not a real approach to the window limit — exactly the #17959 symptom (context_window.used_percentagenot matching the real/internal figure).The harm this issue raises is that the same summed figure also feeds the auto-compaction trigger, so a complete fix needs both the statusline and the auto-compaction trigger to use the executor's real context and exclude server-tool sub-iteration re-reads of already-cached content.
Honest cost (so the multiplier isn't misread)
1,156,259is the same ~385K counted 3× atcache_readrate (~0.1×) — cheap (~115K full-rate-equiv).advisor_messageforward: ~396K full-rate input + 6K output, once.Environment: Claude Code
2.1.150,claude-opus-4-7[1m], Anthropic API, macOS, Ghostty/zsh.Still happens on v2.1.156. I ran into it with Opus 4.8 (1M) today.
The advisor() double-count is nasty because the
usagefields in the JSONL show the inflated sum, which is what CC's auto-compact trigger reads — so from CC's perspective you've "hit 1M" even though the actual transcript is half that.cozempic (github.com/Ruya-AI/cozempic) helps in two ways here, though I want to be honest about what it can and can't do: it doesn't fix the double-counting in CC's token reporting. What it can do:
cozempic current --diagnosereads the raw per-message token counts directly from the JSONL and gives you the real context footprint independent of the runningusagetotal. If you're seeing 1M reported but the actual accumulated transcript is ~500K, the diagnose output will show the discrepancy — which at minimum tells you whether you're hitting a real limit or a counting bug.pip install cozempic/pipx install cozempic. Given this bug has been reproducing on 4.6, 4.7, and 4.8 across multiple people — would be curious whether the diagnose numbers match what you're seeing or surface something different.Still not fixed.
An abysmal bug and still an issue 2 months later!
Still occurs on v2.1.196.
Same root cause without
advisor()— plainmessagecontinuation/retry iterations also trigger itI hit the same premature auto-compaction mechanism described here, but with no advisor call anywhere in the session — every entry in the
iterationsarrays is"type": "message". This suggests the fix belongs in the compaction accounting (it should use the actual prompt size of the last/largest single call, not the summed top-levelusage), not in the advisor tool specifically.Environment
claude-sonnet-5(no 1M variant, no advisor, no custom compaction overrides)a398982a-2ad8-48a5-9560-95c2b60fc539— 44 minutes, 3 auto-compactionsEvidence from the session JSONL
Each
compact_boundary'spreTokensmatches the summed multi-iteration usage of the preceding assistant turn, roughly 2x the real context of the largest single API call:| Compaction |
preTokens| Largest single iteration (real context) | Inflation ||---|---|---|---|
| #1 (auto) | 269,302 | ~131k (
in=709, cache_read=130,705) | ~2.0x || #2 (auto) | 167,697 | ~65k (
in=55,291, cache_read=9,629— cache-miss full resend) | ~2.6x || #3 (auto) | 171,976 | ~87k (
in=640, cache_read=84,035) | ~2.0x |Iteration breakdown for the turn preceding compaction #2 (top-level usage is the sum of all three calls):
The third iteration is a cache-miss retry that re-sent the conversation uncached (~55k real context), yet the summed total (~166k) is what the compaction trigger saw. Compaction #2 fired when the window was roughly a third full.
Impact: the three compactions burned ~8.5 minutes of a 44-minute session (
durationMs263,741 / 109,517 / 136,274) and repeatedly discarded working context that was nowhere near the limit. Because retries/continuations can happen on any model, this isn't limited to extended-context models or advisor users.