Opus 4.8 returns empty thinking blocks — no thinking shown in chat (same regression as Opus 4.7 #49268)

Status Open
Reported on v2.1.154
Maintainer reply None cached
Activity 11 comments · opened May 28, 2026

Summary

Extended thinking is never displayed in the chat when using claude-opus-4-8, even with thinking enabled and a high effort level. The model returns thinking blocks with an empty thinking field, so the UI has nothing to render. Switching the same session to claude-sonnet-4-6 or claude-opus-4-6 immediately restores visible thinking summaries.

This appears to be the same regression already reported for Opus 4.7 (#49268, #49555, #56356, #49322, #49902, #54348) — the harness does not request display: "summarized" for models whose API default is display: "omitted". Opus 4.8 also defaults to omitted, so it reproduces the exact same problem. Filing this so 4.8 is tracked explicitly, since every existing report mentions only 4.7.

Environment

  • Surface: VS Code extension anthropic.claude-code@2.1.154 (CLI backend @anthropic-ai/claude-code@2.1.90)
  • OS: Windows 10 Pro 10.0.19045
  • Model: claude-opus-4-8 (1M context)
  • Effort level: xhigh
  • Relevant settings: no MAX_THINKING_TOKENS override; no showThinkingSummaries; default thinking config

Steps to reproduce

  1. Open the Claude Code VS Code extension.
  2. Select model claude-opus-4-8 (effort level xhigh).
  3. Send any prompt that should trigger reasoning (e.g. a non-trivial debugging or design question).
  4. Observe the chat.

Expected

A collapsible/inline "Thinking" section appears with summarized reasoning, as it does on Sonnet 4.6 / Opus 4.6.

Actual

No thinking is shown at all. There is no expandable thinking section, or it is empty. Ctrl+O (verbose) and Alt+T (toggle thinking) do not bring it back.

Root cause (as identified in #49268)

Newer Opus models (4.7 and 4.8) changed their API default from display: "summarized" to display: "omitted" (to reduce time-to-first-token). The API therefore returns thinking blocks whose thinking content is empty unless the client explicitly requests display: "summarized". Claude Code does not set this for these models, so:

  • The summary is never requested → the API returns empty thinking → the UI renders nothing.
  • Per #56356, even passing --thinking adaptive --thinking-display summarized does not fix it.

Related issues (all reference Opus 4.7)

  • #49268 — Thinking summaries missing on Opus 4.7 — harness doesn't set display: "summarized" (canonical root cause)
  • #49555 — [FEATURE] Allow forcing extended thinking on Opus 4.7
  • #56356 — Opus 4.7 returns no thinking blocks even with --thinking adaptive --thinking-display summarized
  • #49322 / #49902 — Opus 4.7 thinking summaries not rendered (VS Code extension)
  • #54348 — Thinking block in VS Code extension is unclickable / won't expand on Opus 4.7

Workaround

Switch the session to claude-opus-4-6 or claude-sonnet-4-6 (both default to display: "summarized") with /model claude-opus-4-6.

Request

Have the Claude Code harness explicitly request display: "summarized" for models that default to display: "omitted" (Opus 4.7, Opus 4.8, and any future model with the same default) whenever thinking is enabled, so users on the latest Opus models can read thinking summaries in the chat again.

View original on GitHub ↗

11 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/49268
  2. https://github.com/anthropics/claude-code/issues/59844
  3. https://github.com/anthropics/claude-code/issues/56356

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

jonlepage · 3 months ago

it not duplication it for 4.8

jasonnickel · 3 months ago

Independent reproduction on macOS + binary-level confirmation of the root cause — and please don't auto-close this as a 4.7 duplicate.

Reproduced on a different OS than the original report: macOS / Apple silicon (Darwin 25.5.0), VS Code 1.122.0, anthropic.claude-code@2.1.154, model claude-opus-4-8[1m]. The built-in Chat shows only a live thinking-token counter and no thinking text; switching the same chat to claude-sonnet-4-6 instantly restores visible summaries. So it isn't platform-specific.

Confirmed directly in the harness binary (resources/native-binary/claude inside the 2.1.154 extension), not just inferred from behavior — the binary embeds the migration doc for thinking.display:

### thinking.display — opt back into summarized reasoning (Opus 4.7) | Python | thinking={"type": "adaptive", "display": "summarized"} | | TypeScript | thinking: { type: 'adaptive', display: 'summarized' } |

and documents the default flip as a "silent change from Opus 4.6 where the default was to return summarized thinking text." The model capability schema also exposes adaptive-thinking-only ("thinking": {"types": {"enabled": {"supported": false}, "adaptive": {"supported": true}}}).

The only documented restore path is that SDK request parameter — there is no user-facing setting, env var, or render toggle in the harness for it. That's why MAX_THINKING_TOKENS, showThinkingSummaries, the VS Code chat.agent.thinkingStyle render setting, Ctrl+O/Alt+T, and even rolling the extension back to 2.1.153 all change nothing — they're downstream of an empty thinking field.

On the duplicate flag: the mechanism is shared with #49268, but every existing report is filed against 4.7. 4.8 needs to be tracked explicitly, or it'll be assumed fixed when 4.7 is. The fix is one behavior: whenever thinking is enabled, have the harness request display: "summarized" for any model whose API default is omitted (4.7, 4.8, and any future model that ships with that default).

cogitoworks · 3 months ago

Third surface + an empirical check of @jasonnickel's showThinkingSummaries point + a same-app surface mismatch — and a vote against the auto-close.

Reproduced on yet another surface: Windows, Claude Desktop's Code tab (app build 1.9659.2, bundling Claude Code engine 2.1.156 per the session-JSONL version field — newer than the 2.1.90 backend in the issue body). Model claude-opus-4-8[1m], effort xhigh.

I parsed the thinking blocks straight from the session JSONL. On Opus 4.8 every block is structurally present but empty — thinking: "" (length 0), signature only (~3.1k chars). In this one session Opus 4.8 logged 24 turns with zero thinking text (22 on the pre-update engine 2.1.121, then 2 more after upgrading to 2.1.156 — no change). Switching model mid-session restores text instantly on the same harness:

claude-opus-4-8   (2.1.121 x22, 2.1.156 x2)  thinking_len = 0  (all 24)
claude-sonnet-4-6                             thinking_len = 1306, 351, 670
claude-opus-4-6                               thinking_len = 1599, 1674, 176, 283, 1005, 850, 157, 981, 606, 102

Empirical confirmation of @jasonnickel's binary-level point: he noted showThinkingSummaries is downstream of the empty thinking field and shouldn't help. I tested it directly — added "showThinkingSummaries": true to settings.json, fully restarted Claude Desktop, confirmed the same session resumed. Opus 4.8 stayed at length 0. So the one user-facing setting that sounds like it should fix this provably does not, on this surface.

Same app, two surfaces, opposite behavior: in the very same Claude Desktop install, the Chat tab renders summarized thinking for claude-opus-4-8, while the Code tab (this report) shows nothing for the same model. Whatever Chat does to obtain those summaries — presumably the display: "summarized" request @jasonnickel found embedded in the binary — the Code harness isn't doing. The capability plainly exists in-product; it just isn't wired up on the Code path. That also rules out any "4.8 simply doesn't return summaries" explanation — it clearly does, one tab over.

Net: omitted-by-default on Opus 4.8 now reproduces across macOS + Windows, VS Code extension + Claude Desktop Code, and engine builds through 2.1.156, with no user-facing knob (showThinkingSummaries, MAX_THINKING_TOKENS, Ctrl+O / Alt+T) changing it. This isn't a stale 4.7 duplicate — please keep it open and tracked for 4.8. (Also commenting to push back on the 3-day auto-close.)

BinSlayer01 · 3 months ago

Confirmed at the wire level: --thinking-display is parsed but the display field is never serialized into the request (Bedrock).

This issue suspects the flag "may not be properly serialized." I captured the outgoing request and can confirm that's exactly what happens.

Setup

  • Claude Code 2.1.158 (native binary, VSCode extension)
  • CLAUDE_CODE_USE_BEDROCK=1, model global.anthropic.claude-opus-4-8
  • showThinkingSummaries: true, effort: max

Method

Ran the headless CLI through a local logging proxy via ANTHROPIC_BEDROCK_BASE_URL to capture the exact body sent to Bedrock:

claude -p "..." --thinking adaptive --thinking-display summarized \
  --effort high --output-format stream-json --verbose \
  --model global.anthropic.claude-opus-4-8

Captured request body (Opus 4.8)

"thinking": { "type": "adaptive" },
"output_config": { "effort": "high" }

No display field — despite passing --thinking-display summarized. The response comes back with a thinking block that has thinking: "" and a signature only (the server's omitted default).

Control: the same backend works when display is actually sent

Hitting Bedrock directly with curl:

"thinking": { "type": "adaptive", "display": "summarized" }

returns real summarized reasoning (~192 chars) on both claude-opus-4-8 and claude-opus-4-7, e.g.:

I'm applying the Euclidean algorithm to find the GCD of 1071 and 462, working through successive divisions until I reach a remainder of zero, which gives me 21...

Takeaways

  • Provider-independent. Bedrock honors display: "summarized" correctly — Claude Code just never sends it. Consistent with #49268 reporting the same on the direct API.
  • showThinkingSummaries: true can't help — it controls rendering, not the outgoing request.
  • The #49268 fix (harness explicitly sets display: "summarized" for omitted-default models when thinking is enabled) would resolve this. Separately, --thinking-display should actually be serialized when passed — right now it's silently dropped.
kangarko · 3 months ago

Huge failure for Anthropic for hiding thinking. Many times I just stop the chat when I notice it's pulling in the wrong direction instead of having to now having to wait for the hidden thinking block to finish.

Not to mention the thinking block offers slightly different perspective on personal topics which many times was very interesting to read.

Bring it back.

m2de · 2 months ago

CC isn't dropping display arbitrarily — it gates it by provider, and Bedrock/Vertex are excluded.

  1. Thinking enabled (CLAUDE_CODE_DISABLE_THINKING unset).
  2. Model supports interleaved thinking (true for Opus 4.8; only claude-3-* excluded).
  3. Experimental betas not disabled (CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS unset, not HIPAA).
  4. Provider ∈ firstParty (Anthropic API), anthropicAws, foundry (Azure).

If any fail, display is forced to undefined and stripped.

The decisive one is 4: CLAUDE_CODE_USE_BEDROCK → "bedrock" and CLAUDE_CODE_USE_VERTEX → "vertex", neither in the allow-list.

So on Bedrock and Vertex the CLI silently drops display regardless of --thinking-display summarized or the SDK thinking.display field.

Siigari · 2 months ago

Comment draft for #63358:

Found a local workaround that confirms where the fix needs to go in the source.

In the minified cli.js (npm package, @anthropic-ai/claude-code), the thinking display default is assembled here:

x6=R8?_.display??void 0:void 0

This x6 becomes the display field in {type:"adaptive",display:x6} and {budget_tokens:f8,type:"enabled",display:x6} for every inference call. When _.display is undefined (not set by the caller), x6 is undefined, which causes the API to default to "omitted" for 4.7/4.8.

Fix: change void 0 to "summarized" as the fallback:
x6=R8?_.display??"summarized":void 0

Applied this patch locally and confirmed thinking blocks now show summaries in VSCode with opus 4.8 The secondary location is in extension.js where thinkingConfig is built — the s0 fallback path also omits display.

<img width="674" height="248" alt="Image" src="https://github.com/user-attachments/assets/be72e635-c552-455a-a9e6-fb741af122bc" />

Hope this helps pin the exact line in the TS source.

phase3dev · 2 months ago

Consolidating my two earlier follow-ups into one comment with current info.

A recent extension update (see "Notes" below) changed how the CLI is launched, so some of what I posted before is now out of date.

Root cause (confirmed: native-binary installer 2.1.169 + VS Code extension 2.1.169; Ubuntu 24.04, Windows 11 64-bit):

On 4.7/4.8 the API defaults thinking.display to omitted, so unless the client sends thinking: {type: "...", display: "summarized"}, the thinking block comes back empty. In the CLI binary:

if (z.thinkingDisplay==="summarized" || z.thinkingDisplay==="omitted") pz.display=z.thinkingDisplay; // --thinking-display flag (ungated)
else if (!p6() && EK8()) pz.display="summarized"; // p6()===!isInteractive, EK8()===showThinkingSummaries

Two ways to set display:

The --thinking-display flag (always honored), or showThinkingSummaries (honored only when interactive). VS Code and headless -p/SDK run non-interactively (--input-format stream-json), so the setting branch never fires. The extension forwards --thinking-display only when its own config already has display set, which it never maps from showThinkingSummaries ("summarized" appears 0x in extension.js). The x6 = R8 ? _.display ?? void 0 : void 0 line @Siigari found is the same gap in the npm cli.js. The ungated lever is the --thinking-display summarized flag.

Notes:

One of the 2.1.16x updates changed two things on the VS Code path: (1) it signals a real run with --max-thinking-tokens <N>, not --thinking adaptive (adaptive is still used for adaptive mode / SDK / older builds; headless still uses -p); (2) the official claudeCode.claudeProcessWrapper setting uses a process-wrapper convention, launching <wrapper> <REAL_CLAUDE_PATH> <args...>, so a wrapper must consume that leading path. Also the minified array variable was renamed (B -> q in 2.1.169), so a fixed find/replace stops matching after an update.

Workarounds:

  1. Custom launcher, recommended (shell script on Linux; small Node script compiled to a standalone .exe on Windows)
  2. One-line extension.js patch with a script that handles the variable rename.
  3. Local proxy approach, not yet tested.

Created a small repo that includes the current launchers, patch script, CC_THINKING_DISPLAY=omitted toggle, the safe-undo caveat, and environment details:

https://github.com/phase3dev/claude-code-workarounds

betovildoza · 2 months ago

I found that in Claude Code for VS Code v2.1.178 it has been fixed and with the toggle on the right (in previous versions it was on the left) the Thinking block is displayed

<img width="463" height="500" alt="Image" src="https://github.com/user-attachments/assets/818e3f93-5c34-410f-a406-01a7d25c3b58" />

phase3dev · 1 month ago

I wanted to update my earlier comment above:

The original diagnosis is now partly superseded. The newer extension builds appear to have fixed the original client-side mapping highlighted in my initial comment. In my current testing, the request body does correctly contain:

"thinking": {"type":"adaptive","display":"summarized"}

However, Anthropic appears to be engaging in some sketchy practices. There is now a related server-side failure which is keyed to an experiment assignment by Anthropic (no notice, no opt-in, settings silently overridden).

Findings:

  1. On 2026-07-07, my install received a cached experiment assignment in ~/.claude.json:
"experimentKey": "claude_code_attic_parcel_experiment",
"atis": "attic-parcel-meridian"
  1. The Claude Code binary attaches that assignment to requests as an x-cc-atis header.
  1. With that header present, claude-opus-4-8 returns signed thinking blocks with thinking.length === 0, even though the request explicitly asks for summarized thinking.
  1. Stripping only the x-cc-atis header in flight makes the same request return populated thinking again.
  1. Other tested models still return populated summaries under the same flags: Opus 4.7, Sonnet 5, Haiku 4.5, and Fable 5. The observed blanking is specific to Opus 4.8 in this experiment bucket.
  1. DISABLE_GROWTHBOOK=1 alone is not enough if the assignment is already cached. The cached atis token still gets sent. The mitigation is to purge the cached assignment from ~/.claude.json and launch with DISABLE_GROWTHBOOK=1 so it does not immediately re-enroll.

There is also a separate issue from the same day: the native CLI silently self-updated from 2.1.202 to 2.1.203 even though "autoUpdates": false was set. (This does not appear to be the cause of the thinking-summary blanking, since summaries continued working for hours after that update and the blanking reproduces across 2.1.201 through 2.1.204 once the experiment assignment is cached. But it is still a separate and IMHO a very serious updater/control problem.)

UPDATE 2026-07-08:
The mitigation documented above (purge the cached assignment + DISABLE_GROWTHBOOK=1) stopped working within a day. The CLI's startup bootstrap fetch re-enrolls the install about one second after launch, ignoring the variable. The only working user-side opt-out is now purge + CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, which also disables Projects sync, DesignSync, /feedback, live preview, and telemetry.

I filed a new issue here which provides a lengthy overview: https://github.com/anthropics/claude-code/issues/75607#issue-4836011142