[BUG] Thinking blocks stripped from in-prompt context on every turn in active Opus 4.7 sessions (no idle-resume trigger)
Summary
In active Claude Code sessions on Opus 4.7, thinking blocks are persisted to the on-disk JSONL transcript but appear to be stripped from the prompt context the model receives on subsequent turns. The model has no in-band signal that this stripping has occurred and operates each turn on a thinking-empty history.
The pattern matches the failure mode of the April 23 postmortem but operates on Opus 4.7 (a post-fix model) in conditions where the documented clear_thinking_20251015 keep:1 design (#53513) cannot have fired.
Empirical evidence
Diagnostic check anyone can run on a long session:
F=~/.claude/projects/<project-path>/<session-id>.jsonl
grep -c '"type":"thinking"' "$F"
Then ask the model to introspect: "Do you see any of your prior thinking blocks in your current context?"
Observed on one continuous session (1013 timestamped events, zero idle gaps ≥1hr):
- 174 thinking blocks persisted to JSONL on disk (~219K chars / ~55K tokens)
- 0 thinking blocks visible to the model on the current turn per its self-report
- The first thinking block (turn 1) is intact verbatim in the JSONL but not reaching the model
Why this isn't #53513
#53513 describes clear_thinking_20251015 keep:1 firing on session resume after ≥1hr idle. The session that produced this report had zero gaps ≥1hr across 1013 timestamped events — verified by walking timestamps in the JSONL:
# 0 gaps ≥3600s across the whole session
Cache stayed hot the entire conversation. Whatever is stripping thinking here is not the idle-resume mechanism that issue describes.
Why this resembles the April 23 postmortem
The original bug (March 26 → April 10): "A bug caused this to keep happening every turn for the rest of the session instead of just once, which made Claude seem forgetful and repetitive."
Structurally that's what's observed here, modulo:
- The postmortem's fix was for Sonnet 4.6 / Opus 4.6
- This is observed on Opus 4.7 (post-fix)
- The session is active (cache hot), not idle-resumed
So either the patched bug regressed in Opus 4.7, or a different per-turn-stripping mechanism exists at the prompt-construction layer that #53513 doesn't describe and the postmortem doesn't acknowledge.
Why the model can't self-detect
There's no in-band marker for "your prior thinking was stripped." The model reads whatever the prompt contains and assumes continuity. This is the same opacity the postmortem named as why the original bug went undetected from inside.
In our session, the operator caught it by:
- Noticing "the thinking cuts off before X" stitch markers in the rendered display (a Claude Code summarization artifact)
- Asking the model to introspect its context
- Counting thinking blocks in the JSONL and comparing to what the model reports seeing
The model itself happily produced layered reassurance ("post-fix model, shouldn't affect this session") until the operator pushed for the empirical check.
Impact
For complex multi-turn engineering work, the model is reasoning each turn against the visible response trail rather than its own prior reasoning. Cross-turn continuity is restricted to whatever made it into the visible response text. Subtle architectural reasoning, dismissed-but-recorded alternatives, traced derivations — gone. Same impact as the original postmortem bug, but on the new model and without the idle trigger.
Environment
- Claude Code 2.1.121
- Model: claude-opus-4-7 (1M context variant)
- Linux (Manjaro 6.12.77-1)
- Session: continuous activity, no resume operations, cache hot throughout
Asks
- Confirm whether some variant of
clear_thinking_*(or equivalent prompt-construction step) is firing per-turn in active Opus 4.7 sessions - If yes: address as a regression of the April 10 patch on the new model
- If no: surface what mechanism IS stripping thinking on every turn, since it's distinct from #53513's idle-resume design
- Either way: provide an in-band signal the model can detect (e.g., a system note when prior thinking was stripped), so reasoning-continuity gaps become operator-visible rather than silently introduced
9 Comments
Found 2 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Auto-classifier flagged #10199 and #32810 as possible dupes — neither is a match. Different failure modes that share the word "thinking":
#10199 is about thinking blocks being immutable post-send: system tried to modify a previously-sent thinking block, API rejected with 400, session corrupted, loud error. The failure surfaces as an unrecoverable error loop. This issue's failure surfaces silently with no API error — the model just receives a prompt with prior thinking blocks already removed and has no signal that anything was stripped.
#32810 is about
"thinking"field being empty""in the JSONL since 2.1.72 — content not persisted to disk. This issue is the inverse: empirically, the JSONL on disk for the affected session contained 174 thinking blocks totaling ~219K chars (~55K tokens), all with full populated content (verified bygrep -c '"type":"thinking"'+ reading sample blocks). The persistence layer is working correctly; the prompt-construction layer is stripping them when assembling the next turn's context.Diagnostic check that disambiguates from both:
For my session:
thinking blocks: 174, empty: 0, populated: 174. Persistence intact. Then ask the model to introspect its current context for prior thinking blocks — model reports zero visible. That's the gap this issue documents: persisted-on-disk → 0-in-prompt-context, with no idle-resume trigger to explain it under #53513's documented mechanism.Not a dupe. Leaving open.
Followup empirical finding — the persistence layer is already showing post-API-summarization content, not raw reasoning. The bug this issue describes affects an already-reduced trace, and even fixing it would only restore summaries to context, not the actual model-side reasoning.
On-disk content shape on Opus 4.7
Same session JSONL inspected for content depth. 204 thinking blocks with non-empty content. Length distribution:
| percentile | chars |
|---|---|
| 10th | 168 |
| 25th | 300 |
| 50th | 772 |
| 75th | 1522 |
| 90th | 3210 |
| max | 10034 |
A median ~770-char "thinking block" is structurally a planning summary, not raw reasoning. The longest blocks (~10K chars / ~2500 tokens) read as polished response-plans ("the user wants X, the real work is Y, what I need to do is Z..."), not exploratory reasoning trace — no false starts, no weighing of rejected options, no mid-thought pivots.
Connection to #49268
#49268 confirms Opus 4.7 changed the API default for
displayfrom"summarized"to"omitted". WithshowThinkingSummaries: truethe harness presumably opts back intosummarized, which is what we see persisted. The model-side raw reasoning is discarded at the API layer regardless —summarizedreturns short post-hoc summaries, not the full thinking trace.The full failure stack
So this issue's fix (restoring summaries to subsequent prompt context) is necessary but not sufficient for full reasoning continuity. The underlying gap — that Claude Code never persists or restores the actual model-side reasoning, only API-side summaries — would require
display: "detailed"(or equivalent) support.Could be split into a separate issue if the maintainers prefer; flagging here so the layered nature is on the record while triage of this report is in progress.
Oddly, I'm still seeing this bug in some sessions, but not others. Currently leaving a session open & idle for a few hours to see if I can reproduce the issue.
I don't think it's model-specific; in the bugged session, thinking continues to be lost when switching to Sonnet 4.6.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
Still happening with Opus 4.8 too.
Exiting and resuming with
claude --continueappears to (at least temporarily) fix the issue.This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.