[BUG] /context shows 76% header but Messages category shows 138.7% — "Context limit reached" on resume of session within stated free space
Summary
After resuming a session that was closed the previous evening at ~74% context (26% free), the next message attempt is rejected with Context limit reached · /compact or /clear to continue. The /context command output is internally inconsistent: the header reports 764.2k/1m tokens (76%) while the per-category breakdown lists Messages: 1.4m tokens (138.7%). The numbers cannot both be true. The displayed header gives no indication that the session is actually over the limit, so the rejection feels like a regression of the resume token-accounting behavior.
This appears to be a remaining variant of the bug reportedly fixed in v2.1.98 ("Fixed /context Free space and Messages breakdown disagreeing with the header percentage") and is also closely related to #46047 ("Resumed conversations incorrectly recount context tokens as new usage", closed as duplicate).
Reproduction
- Use Claude Code with model
claude-opus-4-7(1M context variant) for a long session involving many largetool_resultpayloads (in my case: MCP tool calls returning ~100–800 KB JSON each, plus several largeReadresults and Chrome DevTools screenshots). - Trigger one or more in-session compactions until the session contains ≥ 4 compaction summary markers.
- Close Claude Code at a context level that the header reports as ~74% used / 26% free.
- The next day, \
claude --resume <session-id>\to continue. - Run \
/context\and observe the inconsistent header vs. per-category numbers. - Try to send any message.
Expected behavior
Either:
- (a) The header \
% used\reflects the actual tokens that will be sent to the API, and a session at 76% should accept at least one further message, or - (b) If the session truly is over the model context limit, the header should also display ≥ 100%, not 76%.
The two displays must agree, and the displayed value must match what the API server enforces.
Actual behavior
\/context\ output (verbatim):
\\\`
Context Usage
764.2k/1m tokens (76%)
claude-opus-4-7[1m]
Estimated usage by category
⛁ System prompt: 9.7k tokens (1.0%)
⛁ System tools: 17.4k tokens (1.7%)
⛁ MCP tools: 18.7k tokens (1.9%)
⛁ Custom agents: 675 tokens (0.1%)
⛁ Memory files: 10.6k tokens (1.1%)
⛁ Skills: 2.4k tokens (0.2%)
⛁ Messages: 1.4m tokens (138.7%)
⛁ Compact buffer: 3k tokens (0.3%)
\\\`
Sum of the categories ≈ 1.46M, header reports 0.764M. Sending any message returns:
\\\\
Context limit reached · /compact or /clear to continue
\\
Environment
- Claude Code: 2.1.114
- Node: v22.20.0
- OS: Ubuntu 24.04.3 LTS on WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2 x86_64)
- Plan: Max
- Model: \
claude-opus-4-7[1m]\(1M context)
Session evidence
I was able to inspect the session JSONL on disk (\~/.claude/projects/<project>/<session>.jsonl\):
- File size: 21.5 MB
- Lines: 5819
- Tool-uses recorded: 1787
- Compaction summary markers in stream: 4
- Pre-compact region (before the latest compaction summary): 6 MB
- Post-compact region (latest compaction summary + everything after): 14.5 MB
- Largest 15 \
tool_result\payloads in the post-compact region: 1.96 MB combined (largest single result: a 195 KB Chrome DevTools screenshot, present twice in the file with the same \tool_use_id\— once at line 127 in pre-compact, once at line 2736 in post-compact, byte-identical)
The presence of identical pre/post-compact \tool_result\ duplicates with the same \tool_use_id\ strongly suggests resume-time recounting (cf. #46047): the same payload is being held in memory and counted both as part of the pre-compaction history and as a fresh post-resume tool_result.
Pre-compact references from post-compact messages confirm the linkage:
- 1617 of 3167 post-compact \
parentUuid\values point at pre-compact \uuid\s - 588 of 1118 post-compact \
tool_result.tool_use_id\values point at pre-compact \tool_use\IDs
So the post-compact region cannot be safely trimmed by simply deleting the pre-compact region (UUID/tool-use chain would break), but the CLI also seems to be sending — or accounting for — both regions in full, even though the latest compaction summary is supposed to replace pre-compact content for the API stream.
Workaround attempted
I duplicated the session file, then surgically replaced the \content\ of the 15 largest post-compact \tool_result\ items with a stub string while preserving every \uuid\, \parentUuid\, \tool_use_id\, \type\, and \name\ field. JSONL line count, UUID set hash, parentUuid set hash, and tool_use_id set hash are all byte-identical to the pre-trim file. New file size: 18.64 MB (-1.87 MB).
Result on resume: \/context\ still shows the same \Messages: 1.4m tokens (138.7%)\ discrepancy, and writing is still blocked. This further suggests the counter / API-stream construction is not just naively summing on-disk content — there is some other state (possibly the same recount bug as #46047) that the trim does not affect.
Impact
- Long sessions on the 1M model become unrecoverable: \
/compact\and \/clear\both destroy work that was specifically being preserved by not triggering compaction. - The header \
%\is actively misleading — it suggests the user has plenty of room when they have none. - Trust in \
/context\as a planning tool is broken: I closed the session at a reading I now know was wrong, and could not have predicted the next-day failure.
Suggested investigation
- Audit the \
/context\aggregator: under what conditions can the per-category sum exceed the header total? Make this an internal invariant violation that surfaces a warning rather than two contradictory numbers. - Check whether resumed sessions reload pre-compaction \
tool_result\payloads into the API stream when a compaction summary should already cover them (link to #46047). - Make the enforced token figure (the one the API server will reject against) the canonical value displayed in the header.
Related
- #46047 — Resumed conversations incorrectly recount context tokens as new usage (closed as duplicate)
- #34158 — Context limit reached at ~200K tokens despite 1M context model
- #11335 — Context Remaining Display Shows 0% When ~50% Available
- Changelog 2.1.98 — Fixed /context Free space and Messages breakdown disagreeing with the header percentage (this report shows the fix is incomplete on 2.1.114)
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗