[BUG] Context silently loses 157K tokens with no compaction record, then prompt cache thrashes for 17 minutes

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

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Context silently loses 157K tokens with no compaction record, then prompt cache thrashes for 17 minutes — 21 full-context rewrites, ~25M tokens burned

Environment

| | |
|---|---|
| Claude Code version | 2.1.247 |
| Entrypoint | claude-desktop |
| Model | claude-opus-5 |
| OS | Windows 11 (10.0.26200) |
| Session ID | SESSION-A |
| Date of incident | 2026-08-29, 03:17:43 → 03:34:43 UTC (06:17:43 → 06:34:43 UTC+3) |
| Cache TTL in use | ephemeral_1h on every affected turn |

Summary

At 06:17:43 the conversation context dropped by 157,023 tokens (829,414 -> 672,391) with
no compaction record, no context-editing record, and no error in the session transcript.
Immediately afterwards the prompt cache began thrashing: the session performed 21 full-context
rewrites in 17 minutes
, including 19 consecutive rewrites with zero cache hits, before
recovering on its own.

Two things appear wrong here: (1) context was mutated with nothing recorded to explain it, and
(2) the cache never re-stabilised afterwards for 17 minutes despite the context being otherwise
static and growing normally.

Each rewrite re-wrote ~628,000 tokens. On every single failed turn cache_read_input_tokens
was frozen at exactly 45,659 — the system-prompt prefix only — meaning the cache was being
written and then never read back.

The work being done during this period was trivial: Read and Bash calls averaging ~680
output tokens per turn
.

Timeline (all 27 turns, local UTC+3)

time       context    cache_creation   cache_read   output
06:16:56    829,414              851      828,561      160   healthy
06:17:43    672,391          626,730       45,659    1,050   <== 157,023 tokens vanish + rewrite #1
06:18:06    673,633            1,242      672,389      556   recovered
06:18:28    674,228              595      673,631       87   healthy
06:19:04    674,157          628,496       45,659      516   <== rewrite #2
06:19:21    674,743              586      674,155      160   recovered (last healthy turn)
06:19:47    673,837          628,176       45,659      293   <== rewrite #3
06:20:29    674,907          629,246       45,659      628   <== rewrite #4
06:21:08    678,184          632,523       45,659      843   <== rewrite #5
06:21:42    679,197          633,536       45,659      609   <== rewrite #6
06:22:19    674,175          628,514       45,659      799   <== rewrite #7
06:22:56    675,213          629,552       45,659      785   <== rewrite #8
06:23:32    668,826          623,165       45,659      352   <== rewrite #9
06:24:22    667,475          621,814       45,659      832   <== rewrite #10
06:25:00    669,819          624,158       45,659      796   <== rewrite #11
06:25:38    669,908          624,247       45,659      424   <== rewrite #12
06:26:27    669,314          623,653       45,659      716   <== rewrite #13
06:27:09    672,751          627,090       45,659      710   <== rewrite #14
06:27:55    672,419          626,758       45,659      285   <== rewrite #15
06:28:40    674,169          628,508       45,659      655   <== rewrite #16
06:29:19    676,392          630,731       45,659      707   <== rewrite #17
06:30:04    676,003          630,342       45,659      741   <== rewrite #18
06:30:44    679,585          633,924       45,659      698   <== rewrite #19
06:31:23    680,679          635,018       45,659      658   <== rewrite #20
06:32:00    680,375          634,714       45,659    1,231   <== rewrite #21
06:33:32    681,958            1,583      680,373      610   self-healed
06:33:54    682,624              666      681,956      329   healthy
06:34:43    683,029              405      682,622    1,696   healthy

What did NOT cause this

The session transcript rules out the obvious explanations:

Not an auto-compaction. The entire 1,237-turn session contains exactly two compactions,
both carrying a full compactMetadata record:

| when (UTC+3) | trigger | preTokens | postTokens |
|---|---|---|---|
| 2026-08-25 00:27:04 | auto | 1,000,701 | 10,194 |
| 2026-08-29 01:33:58 | auto | 999,497 | 12,371 |

Neither is near 06:17:43. Both reduce context to ~10-12K, not to 672K. Both recovered cleanly
(cache_creation of only ~23-25K on the following turn). Real compactions in this session behave
correctly.

Not API-side context editing. The only context_management payload in the session reports
{"applied_edits": []} — no edits applied — and is timestamped 03:33:34, not 06:17:43.

Not TTL expiry. See below.

Not an API error. The session's single isApiErrorMessage entry is dated 2026-08-25 20:03:55.

So a 157,023-token removal occurred at 06:17:43 with nothing in the transcript accounting for
it
. Debug logging was not enabled at the time, so client-side detail is unavailable.

Expected vs actual

Expected: whatever mutated the context invalidates the cached prefix once. One expensive
rebuild (~628K cache_creation), then every subsequent turn reads the new prefix from cache
(cache_read ≈ context size, cache_creation ≈ a few hundred tokens).

That is exactly what happened at 06:18:06 and 06:18:28 — so the rebuild did succeed, and the
cache was usable.

Actual: the cache was silently discarded again at 06:19:04 and, after one more brief recovery
at 06:19:21, discarded on 19 consecutive turns from 06:19:47 to 06:32:00. It then recovered
on its own at 06:33:32 with no user action and no change in context size.

On every one of the 21 failed turns cache_read_input_tokens was exactly 45,659 — the
system-prompt/tools prefix, i.e. only the first cache breakpoint matched while every breakpoint
after it missed. The turns in between show cache_read of 672,389 / 673,631 / 674,155, proving a
usable cache entry existed and was simply not being found.

Why TTL expiry does not explain this

  • All 27 turns carry cache_creation.ephemeral_1h_input_tokens — a 1-hour TTL.
  • The 21 rewrites span 17 minutes, at ~40 seconds between turns. No gap approaches the TTL.
  • TTL expiry would produce one rewrite, not 21 with a frozen cache_read value.
  • ephemeral_5m_input_tokens is 0 on every affected turn; only the 1-hour tier was in use.

Impact

| | |
|---|---|
| Turns after 06:17:43 | 27 |
| Full-context rewrites | 21 |
| Total cache_creation | 13,200,895 tokens |
| Total output_tokens for those turns | 14,328 |
| Healthy per-turn cost (measured, same session, 05:20–06:16) | ~75,000 weighted tokens |
| Actual per-turn cost during failure | ~1,264,000 weighted tokens (~17x) |
| Effective tokens spent after 06:17:43 | ~27,003,000 |
| Effective tokens the same work should have cost | ~2,025,000 |
| Wasted | ~24,978,000 weighted tokens |

Weighting used: input×1 + cache_read×0.1 + cache_creation×2 + output×5.

This consumed roughly 36% of a full 5-hour usage window and counted against the weekly limit,
for ~14K tokens of actual output. The 5-hour quota hit 85% within ~20 minutes of the window
rolling over, which is what first surfaced the problem.

Control: a concurrent session that did NOT fail

Session SESSION-B (a different, unrelated project) ran in parallel on the
same machine, same account, same model, same Claude Code version
, and never exhibited this:

| | Control session SESSION-B | Affected session SESSION-A |
|---|---|---|
| Transcript size | 147 MB | 78 MB |
| Peak context reached | 997,323 | 998,040 |
| Total turns | 2,435 | 1,237 |
| Turns with cache_creation > cache_read | 24 | 29 |
| Distribution of those turns | isolated, spread over 7 days | 21 clustered in 6 minutes |
| cache_creation / cache_read ratio, worst 20-min bucket | 0.04 | 3.95 |

The 24 events in the control session are single post-compaction rebuilds that immediately
recovered — the correct behavior. This rules out context size, transcript size, and account-level
state as the cause: the healthy session ran at a larger peak context with a larger transcript.

The control session also compacts regularly and never exhibits an unexplained partial context
drop of the kind seen at 06:17:43.

How to verify

The evidence is in the local transcript. Per-turn usage objects are recorded on type:"assistant"
entries in:

~/.claude/projects/<project-A>/<session-A>.jsonl

Filter to timestamp >= 2026-08-29T03:17:43Z and inspect cache_read_input_tokens — the constant
45,659 across 21 non-adjacent turns is the signature.

To confirm no compaction occurred, grep the same file for compactMetadata — only two matches
exist, dated 2026-08-24T21:27:04Z and 2026-08-28T22:33:58Z.

Note when parsing: deduplicate on message.id first (see secondary issue below).

---

Secondary issue: transcript double-logging inflates any local usage audit

In the same transcript, 785 of 1,237 distinct message.id values are written as 2–3 separate
JSONL entries
, each with distinct uuid but identical usage payloads and identical
requestId. Naive summation over type:"assistant" entries therefore overstates token usage by
~2.12x.

  • Raw assistant entries with a usage object: 2,377
  • Distinct message.id: 1,237
  • Distinct requestId: 1,237
  • Distinct uuid: 2,377

This is reproducible across every session transcript examined (5 sessions, 4 projects). It makes
local usage accounting unreliable unless callers know to deduplicate, and it may affect any
built-in tooling that reads these files. All figures in this report are post-deduplication.

---

Note

Paths, project names and session IDs have been redacted. Full unredacted transcripts and the
analysis scripts used to produce these figures are available on request.

What Should Happen?

I explained everything in "What's Wrong?"

Error Messages/Logs

Steps to Reproduce

I explained everything in "What's Wrong?"

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.247

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗