Thinking summaries missing on Opus 4.7 — harness doesn't set display: "summarized"

Open 💬 47 comments Opened Apr 16, 2026 by yusufmo1

Switched to Opus 4.7 on v2.1.111 and noticed thinking summaries stopped showing up. Took a bit to track down — writing it up in case it's useful.

The extended-thinking API docs note that Opus 4.7 changed the default for the display parameter to "omitted" (Opus 4.6 and earlier defaulted to "summarized"). The reason given is faster time-to-first-token on streaming responses.

The result is the API returns thinking blocks with empty thinking fields by default, so the UI has nothing to render. Setting "showThinkingSummaries": true in settings.json doesn't help — that controls rendering of what the API sends back, not what the API decides to send.

Repro

  1. Run v2.1.111 with "showThinkingSummaries": true set
  2. /model claude-opus-4-7
  3. Ask something that triggers extended thinking
  4. No summaries appear in the UI

Switching to claude-opus-4-6 or claude-sonnet-4-6 brings them back since those still default to "summarized".

Suggested fix
When the selected model defaults to display: "omitted" (currently Opus 4.7 and Mythos Preview per the docs) and the user has showThinkingSummaries enabled, the harness should pass display: "summarized" explicitly in the API request.

Environment

  • Claude Code 2.1.111
  • Model: claude-opus-4-7 (1M context variant)
  • macOS 15.3 (Darwin 25.3.0)

View original on GitHub ↗

47 Comments

yusufmo1 · 3 months ago

Dug into the v2.1.111 binary to confirm what's actually broken. The bug: the showThinkingSummaries: true setting and the API's thinking.display parameter are two completely unrelated systems in the harness — there is no code path that wires one to the other. So enabling the setting can't make summaries come back; whether you get them depends entirely on the model's API default, which Opus 4.7 flipped to "omitted".

here's the request-construction code:

const bH = V_ ? q.display ?? undefined : undefined;
const QH = { type: "adaptive", display: bH };  // sent as the thinking parameter

bH is sourced only from q.display, an internal field on the thinking config object. Nothing reads showThinkingSummaries and assigns it to q.display. So bH is always undefined, the display field drops out of the request, and Opus 4.7 returns empty thinking blocks.

What showThinkingSummaries actually controls — straight from the embedded schema string:

showThinkingSummaries: "Show thinking summaries in the transcript view (ctrl+o). Default: false."

It governs (a) the Ctrl+O transcript-view renderer and (b) whether the redact-thinking-2026-02-12 beta header is sent. Neither has any effect on the API's display parameter. The naming overlap is misleading — a user reasonably assumes the setting controls whether summaries are requested, but it doesn't.

There's a related model-version gate nearby:

const z_ = env.CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING && (model.includes("opus-4-6") || model.includes("sonnet-4-6"));

That allowlist was never extended to 4.7 — same regression pattern: the request-construction code still treats 4.6 as the newest model.

Suggested minimal fix: when showThinkingSummaries === true, set q.display = "summarized" so it flows into bH and onto the request. Or, simpler and more correct: send display: "summarized" unconditionally for any model where the API defaults to "omitted" (currently Opus 4.7 and Mythos Preview), with an explicit opt-out for users who want the latency benefit of "omitted". The 4.6/sonnet-4.6 model checks should also be extended to cover 4.7+.

mjesuele · 3 months ago

Confirmed the diagnosis with a binary patch on v2.1.112 (Linux x86-64).

The request-construction code has:

CH=h$?q.display??void 0:void 0

q.display is never populated from the showThinkingSummaries setting, so CH is always undefined and Opus 4.7's default ("omitted") wins.

Fix: q.display??void 0 and "summarized" are both 17 bytes. Replacing in-place with sed:

cp /path/to/2.1.112 /path/to/2.1.112.bak
sed -i 's/q\.display??void 0/"summarized"     /g' /path/to/2.1.112

Two occurrences patched (offsets 119213276 and 232078516 in my build). Thinking summaries now display correctly on Opus 4.7 with showThinkingSummaries: true. Survives until next claude update.

Nitjsefnie · 3 months ago

Verified --thinking-display summarized restores populated thinking blocks on Opus 4.7 end-to-end (Claude Code 2.1.112, first-party / Max subscription).

Settings alone don't work. Before: ~/.claude/settings.json already had both showThinkingSummaries: true AND thinkingDisplay: "summarized". Persisted jsonl still showed {"type":"thinking","thinking":"","signature":"..."} on every Opus 4.7 turn. A local sweep across all my session jsonls was clean: 2.1.97–2.1.110 with opus-4-6 → 3,399/3,399 populated; 2.1.111 with opus-4-7 → 134/134 empty; 2.1.111 with synthetic helper model → populated. So showThinkingSummaries: true is doing its job at the beta-header level (no redact-thinking-2026-02-12 sent), but matches @yusufmo1's diagnosis that it doesn't feed into q.display — and the 4.7 server default "omitted" wins.

CLI flag works. Same binary, same settings — just launched a new claude session with claude --thinking-display summarized. The resulting jsonl writes populated thinking blocks with valid signatures:

  • L8 block[0]: 202 chars, populated, signature present
  • L23 block[0]: 87 chars, populated, signature present

First-party Max, no binary patch, no CLAUDE_CODE_EXTRA_BODY — just the flag.

Persistence for interactive shells:

alias claude='claude --thinking-display summarized'

Caveat: only affects interactive-shell invocations of claude. Non-interactive callers (cron, systemd, scripts with #!/bin/sh) won't pick up the alias — a wrapper earlier on $PATH than the real binary would cover those.

narner90 · 3 months ago
Verified --thinking-display summarized restores populated thinking blocks on Opus 4.7 end-to-end (Claude Code 2.1.112, first-party / Max subscription). Settings alone don't work. Before: ~/.claude/settings.json already had both showThinkingSummaries: true AND thinkingDisplay: "summarized". Persisted jsonl still showed {"type":"thinking","thinking":"","signature":"..."} on every Opus 4.7 turn. A local sweep across all my session jsonls was clean: 2.1.97–2.1.110 with opus-4-6 → 3,399/3,399 populated; 2.1.111 with opus-4-7 → 134/134 empty; 2.1.111 with synthetic helper model → populated. So showThinkingSummaries: true is doing its job at the beta-header level (no redact-thinking-2026-02-12 sent), but matches @yusufmo1's diagnosis that it doesn't feed into q.display — and the 4.7 server default "omitted" wins. CLI flag works. Same binary, same settings — just launched a new claude session with claude --thinking-display summarized. The resulting jsonl writes populated thinking blocks with valid signatures: L8 block[0]: 202 chars, populated, signature present L23 block[0]: 87 chars, populated, signature present First-party Max, no binary patch, no CLAUDE_CODE_EXTRA_BODY — just the flag. Persistence for interactive shells: alias claude='claude --thinking-display summarized' Caveat: only affects interactive-shell invocations of claude. Non-interactive callers (cron, systemd, scripts with #!/bin/sh) won't pick up the alias — a wrapper earlier on $PATH than the real binary would cover those.

That fix does not seem to be working for me on linux, version 2.1.110

alkautsarf · 3 months ago

Confirming this still happens on 2.1.112 (one version newer than reporter).

Dug into the binary and there's a hidden CLI flag that already does the right thing:

--thinking-display <display>  choices: summarized, omitted   .hideHelp()

Verified end-to-end: launching with claude --thinking-display summarized on Opus 4.7 restores populated thinking blocks. So the API plumbing is wired — the gap is that:

  1. The flag is .hideHelp(), so claude --help doesn't show it (hard to discover)
  2. There's no equivalent settings.json key, only alwaysThinkingEnabled (boolean enable/disable, doesn't control display)
  3. The CLI builds {type:"adaptive"} without a display field by default, so the request inherits Opus 4.7's new display:"omitted" default

Suggested fix (small surface):

  • Un-hide --thinking-display from --help
  • Add a thinkingDisplay: "summarized" | "omitted" settings.json key that maps to the same flag, so users on 4.7 can persist the preference without wrapping claude in a script
  • Bonus: when alwaysThinkingEnabled: true is set with no explicit thinkingDisplay, default display to "summarized" (matches user intent — they enabled thinking because they want to see it)

Workaround for anyone reading this: add --thinking-display summarized to your launcher wrapper.

Hammaarn · 3 months ago

Adding a workflow-impact voice to this thread — the existing comments cover diagnosis and workarounds well, but the severity case hasn't been made from a power-user angle.

My orchestration system is architected around visible reasoning: agent dispatch targeting, lens activation decisions, verification-before-completion, panel reviews. I don't use reasoning visibility as a UX nicety — it's the primary surface I use to catch misinterpretations before code is written, sanity-check dispatches before approving, and debug decisions in flight. On 4.7 with the current default, that entire layer is opaque. The functional downgrade is substantial.

Separately, the naming collision is genuinely misleading: showThinkingSummaries: true sounds like it controls whether summaries are requested. It doesn't, and the gap between "setting enabled" and "no summaries appearing" reads as a bug long before a user thinks to check the API default.

Proposed priority: promoting --thinking-display out of .hideHelp() and adding a thinkingDisplay settings.json key is a few lines of code for substantial workflow recovery. Developer-tool audiences are not the same audience as consumer-chat — the default for Claude Code probably shouldn't inherit the latency-optimized API default.

Also upvoting the suggestion that alwaysThinkingEnabled: true with no explicit thinkingDisplay should default to "summarized" — matches user intent.

geraertsf · 3 months ago

Another +1 on 2.1.112 macOS with claude --thinking-display summarized aliased. Posting the raw jsonl diff since prior comments described it but didn't show it side-by-side from the same setup:

Before the alias, same settings.json:

{
  "type": "thinking",
  "thinking": "",
  "signature": "<redacted>"
}

After the alias, next session, nothing else changed:

{
  "type": "thinking",
  "thinking": " The user is asking in French, so I'll respond in French without any special formatting. To find the trailing zeros in 100!, I need to count how many times 10 divides into it, [...]",
  "signature": "<redacted>"
}

Signature is issued in both cases — only the thinking text differs, exactly matching @yusufmo1's diagnosis.

NtTestAlert · 3 months ago

So ofc there is no way to turn this on from the desktop app. Which just had thinking display re-introdouced in the previous update this week. Peak.

Vibecoded by Claude (only for windows): https://github.com/NtTestAlert/claude-thinking-summary-wrapper

Works for desktop app for default, if you wrap cli, probably VSCode etc too.

ccclapp · 3 months ago

I had posted about same problem and read the solution here. I Primarily working via studio in the Claude Code Extension and it did not solve the problem there. Here's the solution that worked for me in VS studio Below is the copy/paste from CC generated .md file. Attached is the md file itself

github-reply-opus-4-7-thinking-fix.md
:

Working solution for VS Code extension on Windows (Max subscription, Opus 4.7, Claude Code 2.1.112).

The --thinking-display summarized CLI flag works as @alkautsarf noted, but getting it into the VS Code extension via claudeProcessWrapper on Windows has two traps:

  • .cmd/.bat wrappers fail with spawn EINVAL — Node.js spawn() on Windows can't execute shell scripts without shell: true, which the extension doesn't set.
  • PyInstaller + os.execv() silently breaks stdio — no error, but prompts go in and no output comes back. The PyInstaller bootloader's handles get orphaned when execv replaces the inner Python process.

What works: a PyInstaller-compiled Python wrapper using subprocess.run() to spawn claude.exe as a proper child (stdio inherited cleanly), with --thinking-display summarized prepended.

claude_wrapper.py:

import subprocess, sys

CLAUDE_EXE = r"C:\Users\<you>\.local\bin\claude.exe"

def main():
    args = [CLAUDE_EXE, "--thinking-display", "summarized"] + sys.argv[1:]
    try:
        result = subprocess.run(args)
        sys.exit(result.returncode)
    except KeyboardInterrupt:
        sys.exit(130)

if __name__ == "__main__":
    main()

Build:

pip install pyinstaller
pyinstaller --onefile --console claude_wrapper.py

Move dist\claude_wrapper.exe somewhere stable (e.g. C:\Users\<you>\.local\bin\claude-wrapper.exe) and add to %APPDATA%\Code\User\settings.json:

"claudeCode.claudeProcessWrapper": "C:\\Users\\<you>\\.local\\bin\\claude-wrapper.exe"

Reload the VS Code window. The ▸ thinking toggle now expands to live-streaming summaries on Opus 4.7, matching pre-4.7 behavior.

For PowerShell CLI users who just want the flag persistent without compiling anything, add this to your PowerShell profile (notepad $PROFILE — create the file if it doesn't exist):

function claude {
    & "C:\Users\<you>\.local\bin\claude.exe" --thinking-display summarized @args
}

This handles standalone PowerShell sessions only. The VS Code graphical panel still needs the compiled wrapper above — the extension launches its own process and doesn't pick up shell aliases or functions.

Seconding the request from several comments above: a thinkingDisplay key in settings.json (mapping to the same hidden flag) would make all of this unnecessary. Until then, this is what works for Windows + VS Code.

dwaltrip · 2 months ago

PLEASE stop re-hiding the thinking blocks for users who have gone out of their way to get it working again on older versions.

If I set “showThinkingSummaries” to true, it’s for a reason.

If you are trying to deprecate thinking blocks entirely, then just please say it up front. And ideally let us know why.

Thank you. I appreciate the hard work of the Claude code team.

phpmypython · 2 months ago

Posted about this here as well. I've been sed patching the minified JS for months and today they removed the minifed JS entirely so It's gonna be a nightmare trying to bring this back

ccclapp · 2 months ago
Posted about this here as well. I've been sed patching the minified JS for months and today they removed the minifed JS entirely so It's gonna be a nightmare trying to bring this back

If I understand your concern we all share it but I believe the solutions at least temporarily have been posted above by myself for VS studio and cli and others as well check above I think we have good workable temporary solutions until anthropics solves the underlying problem

phpmypython · 2 months ago
> Posted about this here as well. I've been sed patching the minified JS for months and today they removed the minifed JS entirely so It's gonna be a nightmare trying to bring this back If I understand your concern we all share it but I believe the solutions at least temporarily have been posted above by myself for VS studio and cli and others as well check above I think we have good workable temporary solutions until anthropics solves the underlying problem

Here's my workaround for my use case which also involves using the undocumented --thinking-display summarized flag.

ccclapp · 2 months ago

I think the short answer is: 4.7 sucks. The model is nowhere near as intuitive as 4.6 after 18 hours of usage I'm reverting back

betovildoza · 2 months ago

This happened to me too , the thinking blocks completely disappeared.
I spent hours testing every setting, model, and flag (just like many here) until I noticed the /thinking toggle is inverted in v2.1.112. Moving it manually to the left position fixed it instantly for me.
Even if the root cause is the Opus 4.7 harness change, this UI bug can make the summaries disappear anyway.
Worth a quick try.
Related: #49739

Braxbro · 2 months ago

https://github.com/anthropics/claude-code/issues/49622 Happens on Linux too - same pattern. Haven’t verified the workaround yet.

Bizuayeu · 2 months ago

Still reproducing on v2.1.116 — version bump + two small wrapper tweaks

Bumping the affected-version list: the bug is still live on anthropic.claude-code-2.1.116-win32-x64 + claude-opus-4-7. @yusufmo1's diagnosis still holds verbatim and @ccclapp's VS Code + PyInstaller workaround still works. Posting numbers and a couple of incremental tweaks in case they help anyone else.

v2.1.116 numbers (same machine, same settings, wrapper toggled)

| | Thinking blocks | With content | Fill rate |
|---|---|---|---|
| Before wrapper (baseline session) | 41 | 0 | 0.0% |
| After wrapper (fresh session A) | 6 | 6 | 100% |
| After wrapper (fresh session B) | 5 | 5 | 100% |

All blocks in the baseline had signature set and display missing — server-side thinking happening, "omitted" default stripping it on the way back, exactly as diagnosed upthread.

Two small tweaks on top of @ccclapp's wrapper

Both are quality-of-life; the core approach (PyInstaller + subprocess + claudeProcessWrapper) is unchanged.

1. Auto-resolve the extension directory via glob — so the wrapper survives the next Claude Code auto-update without hand-editing a hardcoded version path:

from pathlib import Path
import glob

HOME = Path.home()
EXT_BASE = HOME / ".antigravity" / "extensions"  # or ".vscode/extensions" on standard VS Code
pattern = str(EXT_BASE / "anthropic.claude-code-*-win32-x64")
claude_bin = Path(sorted(glob.glob(pattern))[-1]) / "resources" / "native-binary" / "claude.exe"

2. Set CLAUDE_CODE_EXECPATH explicitly before subprocess.Popen(...) — the bundled binary references this env var internally as its self-path, and setting it to the resolved claude.exe prevents any chance of wrapper re-entry if a subprocess inherits the env:

env = os.environ.copy()
env["CLAUDE_CODE_EXECPATH"] = str(claude_bin)
subprocess.Popen([str(claude_bin), "--thinking-display", "summarized", *sys.argv[1:]], env=env).wait()

Full wrapper (~60 lines including log rotation) is a drop-in replacement for claude_wrapper.py in @ccclapp's steps; PyInstaller build and settings.json line are identical.

One orthogonal note for v2.1.116 specifically

In case anyone else was suspecting the [1m] context-length suffix (claude-opus-4-7[1m]) as a separate capability-table issue — that path is handled in v2.1.116. The lookup table and branch exist:

"[1m]"), q=Z7(H); if(q==="claude-opus-4-7") return $?"Opus 4.7 (1M context)":"Opus 4.7";

So [1m] isn't the problem. The only missing plumbing is still thinking.display, as OP laid out.

Environment

  • Claude Code VS Code extension 2.1.116 (auto-updated today)
  • Antigravity (VS Code fork) on Windows 11
  • Model: claude-opus-4-7 (1M context), first-party Max subscription
Val4evr · 2 months ago

v2.1.116 progress report: thinkingDisplay is half-shipped — runtime reads it, schema blocks it

Partial good news on the thinkingDisplay settings key that @alkautsarf proposed upthread. The read path is now in the binary — it's just blocked by the settings schema.

Runtime reads thinkingDisplay as of 2.1.116

strings on ~/.local/share/claude/versions/2.1.116 shows the request-construction code has been patched from the q.display ?? void 0 pattern documented earlier to an actual settings read:

// ... reads w.maxThinkingTokens (a known settings.json key) ...
if (bT.type !== "disabled" &&
    (w.thinkingDisplay === "summarized" || w.thinkingDisplay === "omitted"))
    bT.display = w.thinkingDisplay;

Same w object that supplies maxThinkingTokens, so thinkingDisplay is clearly intended as a sibling settings.json key. The value flows straight to bT.display, which is the API request's display parameter — exactly the wiring asked for.

But the schema validator rejects it

Attempting to persist it fails at write time:

Settings validation failed:
- : Unrecognized field: thinkingDisplay. Check for typos or refer to the documentation for valid fields

The embedded schema in 2.1.116 lists alwaysThinkingEnabled, effortLevel, showThinkingSummaries, maxThinkingTokens — but not thinkingDisplay. So users can't save the key even though the code would read it if they could.

Net effect for end users

  • Schema fix is trivial — add thinkingDisplay to the JSON schema with enum ["summarized", "omitted"].
  • Until then, the --thinking-display summarized CLI flag is still the only working persistent fix (confirmed end-to-end on 2.1.116 with an alias claude='claude --thinking-display summarized' in ~/.zshrc).
  • showThinkingSummaries: true still doesn't feed into thinkingDisplay automatically, so @alkautsarf's "bonus" suggestion (default display to "summarized" when alwaysThinkingEnabled: true is set) is still unimplemented and would eliminate the footgun entirely.

Environment: macOS 15.x (Darwin 25.3), Claude Code 2.1.116, Opus 4.7 (1M context), first-party Max subscription.

Shadetail · 2 months ago

Confirming repro: Opus 4.7 via VS Code extension, showThinkingSummaries: true in ~/.claude/settings.json. Thinking blocks never render. This matches your diagnosis exactly --- the harness seems to rely on the API-level default, which is now omitted on 4.7, so the setting has nothing to render. Suggested fix: have showThinkingSummaries: true explicitly force display: "summarized" on the request, since that's the only thing the setting can meaningfully do on 4.7.

betovildoza · 2 months ago

I'm finding that the toggle thinking is active, but it doesn't show the block, but if I turn it off, it makes it respond (it shows thinking 2s) and then It's active again; its next response does show the thinking block. Is it related to the bug? (vsc extension)

shawnz · 2 months ago

Copying my note here from https://github.com/anthropics/claude-code/issues/49322#issuecomment-4301009215:

I was previously using the --thinking-display summarized argument, together with the claudeProcessWrapper setting in VS Code, but I noticed it broke some things in the IDE like for example the /plugins command.

As an alternative, you can also set the undocumented environment variable CLAUDE_CODE_EXTRA_BODY. For example, write the following in your ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_EXTRA_BODY": "{\"thinking\":{\"type\":\"adaptive\",\"display\":\"summarized\"}}"
  }
}

You need to set type: adaptive because it's a mandatory parameter and the CLAUDE_CODE_EXTRA_BODY environment variable clobbers any existing objects specified within it (it only does a shallow merge). However, this unfortunately breaks Haiku usage which doesn't support the type parameter.

VS Code users might also want to see this post from @Evey-Vendetta in which they present a more comprehensive claudeProcessWrapper command to fix some of the issues with that approach: https://github.com/anthropics/claude-code/issues/49322#issuecomment-4302154519

anthrotype · 2 months ago
Opus 4.7 via VS Code extension, showThinkingSummaries: true in ~/.claude/settings.json. Thinking blocks never render.

because its effect on the thinkingDisplay only works when claude is interactive, see https://github.com/anthropics/claude-code/issues/8477#issuecomment-4305259256

As an alternative, you can also set the undocumented environment variable

CLAUDE_CODE_EXTRA_BODY breaks Haiku 4.5 (which doesn't support adaptive thinking).

hifihedgehog · 2 months ago

Same bug on Windows / VS Code extension 2.1.x with Opus 4.7. Not macOS-specific.

Root cause is now public (credit to the workaround in #8477 (comment)): Opus 4.7 changed the API default for thinking blocks from display: "summarized" to display: "omitted". The blocks are still in the response stream, but the thinking field is empty unless the caller passes display: "summarized" explicitly. Documented in Anthropic's own migration guide: https://platform.claude.com/docs/en/about-claude/models/migration-guide#migrating-to-claude-opus-4-7

Net effect: showThinkingSummaries, alwaysThinkingEnabled, and viewMode: "verbose" have nothing to render, because Claude Code does not pass display: "summarized" when calling the Opus 4.7 API. showThinkingSummaries is the documented, official way to surface thinking in the VS Code extension, and it is silently broken on Opus 4.7. The settings surface never caught up to the API change.

Two undocumented workarounds (from the same comment):

  1. Add to ~/.claude/settings.json:

``json
{
"env": {
"CLAUDE_CODE_EXTRA_BODY": "{\"thinking\":{\"type\":\"adaptive\",\"display\":\"summarized\"}}"
}
}
``

  1. Hidden CLI flag: --thinking-display summarized

The env var approach works for the VS Code extension since it delegates to the CLI.

Why this is high-priority, not a cosmetic regression:

Visible real-time thinking was load-bearing for the steering loop. With it visible, you could stop the model going down a wrong branch before it spent N turns of token budget on a wrong premise; you could verify it had internalized constraints from CLAUDE.md / memory rather than hallucinated them; and you could audit assumptions before committing to a plan.

With it hidden behind an unexpandable pill, you cannot tell whether a wrong final answer came from a wrong premise or a wrong execution of a right premise. Silent assumption drift becomes invisible until after the wrong action is taken. "Thought for 376s" is a duration, not a signal. It tells you nothing actionable. This is a regression in the developer's ability to supervise the agent.

On the user side: this is a paid product. Pro at $20/month, Max at $100–$200/month. Paying customers should not have to monkey-patch cli.js, reverse-engineer an undocumented CLAUDE_CODE_EXTRA_BODY env var, or scrape issue threads to recover functionality that worked in the previous release of the same product. The workaround being undocumented is itself a bug. The gap between what the API supports and what Claude Code exposes as a first-class setting keeps widening with every model bump.

Related open issues, same root problem:

  • #8477 — original tracking issue where the API-default change was traced and the workaround was published
  • #49757 — empty/unexpandable stub in VS Code extension (Opus 4.7)
  • #49902 — thinking summaries not rendered (VS Code extension 2.1.112)
  • #49322 — thinking summaries not rendered in VS Code extension (Opus 4.7)
  • #48065 — thinking summaries not displayed when showThinkingSummaries enabled
  • #49739 — toggle button inverted, no visual feedback (v2.1.112), likely a related UI-state bug
  • #30958 — earlier transcript/TUI variant of the same regression (v2.1.69)
  • #51131 — extended thinking dropdown no longer expandable in VS Code extension (Opus 4.7)
  • #33163 — "Bring back thinking" feature request, same underlying ask

What would actually resolve this:

  1. Pass display: "summarized" by default for Opus 4.7+ when showThinkingSummaries and alwaysThinkingEnabled are on. Or expose a first-class thinkingDisplay setting alongside the existing thinkingEnabled and effortLevel.
  2. Restore the expandable thinking block in the VS Code extension chat panel so showThinkingSummaries actually shows summaries when the data is present.
  3. Update the docs so they reflect current showThinkingSummaries semantics on Opus 4.7+ instead of describing behavior that no longer applies.
VividNightmareUnleashed · 2 months ago

Adding Claude Desktop (Electron) as a third surface. Same root cause, source-level evidence below. Verified on the v1.5354 desktop bundle and claude.exe 2.1.121, both extracted locally.

One gate, three surfaces

The display: "summarized" branch and the redact-thinking-2026-02-12 beta header are both guarded by !Sq() in claude.exe:

function Sq(){return!g8.isInteractive}

…where isInteractive is set at startup:

A = q.includes("-p") || q.includes("--print")
 || q.includes("--init-only")
 || q.some(M => M.startsWith("--sdk-url"))
 || !process.stdout.isTTY;
EW6(!A);

Any subprocess invocation with piped stdio hits the !isTTY branch, so all three reported surfaces fall into the same dead-code path:

| Surface | Why isInteractive=false |
|---|---|
| CLI piped (CI, scripts) | !process.stdout.isTTY |
| VS Code extension subprocess | piped stdio, no TTY |
| Claude Desktop subprocess (CCD) | piped stdio, no TTY |

Both gated branches:

// display = "summarized" — only fires when interactive
if (O.thinkingDisplay === "summarized" || O.thinkingDisplay === "omitted")
  e4.display = O.thinkingDisplay;
else if (!Sq() && Cq().showThinkingSummaries === true)
  e4.display = "summarized";

// redact-thinking-2026-02-12 beta — same guard
if (_ && EqK(H) && !Sq() && Cq().showThinkingSummaries !== true)
  q.push(NC8);

showThinkingSummaries in ~/.claude/settings.json is structurally a no-op anywhere claude.exe is launched as a subprocess. Matches the reports across this thread, #48065, #49757, #49902, #49322, #51131 — same gate, three frontends.

Confirming the Desktop never compensates

The branch that does fire in non-interactive mode is O.thinkingDisplay, set from the SDK option thinking.display and translated to the --thinking-display flag:

g.type !== "disabled" && g.display && F.push("--thinking-display", g.display)

Searched the Desktop's renderer bundle (app.asar.vite/build/index.js, ~15 MB) for every thinking: / thinkingConfig: callsite. Every match where thinking: is set as an SDK option lives in the cowork/Conway agent runner. The CCD startSession path destructures these:

{ thinking: Y, effort: $, maxThinkingTokens: W, ... }

…and Y is never set for Code sessions. --thinking-display never lands on argv when the Desktop spawns claude.exe. Consistent with the VS Code extension behavior reported above.

Capability gates aren't the blocker

For Opus 4.7 specifically, claude.exe confirms full support for display: "summarized":

function Co8(H){ /* adaptive_thinking */
  ...
  if ($ === "claude-opus-4-7" || $ === "claude-opus-4-6" || $ === "claude-sonnet-4-6") return true;
}
function fh(H){ /* effort — same model set */ }
function d78(H){ /* xhigh effort — only Opus 4.7 */
  if ($ === "claude-opus-4-7") return true;
}

Harness just isn't sending it.

Reproduces on: Windows 11, Claude Desktop 1.5354, claude.exe 2.1.121, Opus 4.7 (1M context). ~/.claude/settings.json has "showThinkingSummaries": true per docs.

vinozganic · 2 months ago

@shawnz's CLAUDE_CODE_EXTRA_BODY workaround has a second breakage beyond Haiku: it kills the WebSearch tool for Claude Code.

With the env var set, every request the harness makes carries thinking: {type: "adaptive", display: "summarized"}. The first time the harness routes through a server-side web_search_20250305 call, the API returns:

API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"Thinking may not be enabled when tool_choice forces tool use."}}

<img width="4849" height="463" alt="Image" src="https://github.com/user-attachments/assets/f185eae9-2d5c-49c0-a105-f60e339ebc9d" />

That's the documented Anthropic constraint — extended thinking is only compatible with tool_choice: "auto" or "none", not {type: "tool"} / {type: "any"}. The web_search server tool evidently forces tool_choice on at least one hop of its orchestration, and a globally-injected thinking object via env var leaves no way to scope it out for that path. WebFetch keeps working because it's a client-side tool with no forced tool_choice, so the breakage is specifically WebSearch.

For me that trade isn't worth it. Losing first-class Anthropic-side web search to a 400 every time you use it is a bigger functional hit than running blind on thinking summaries — at least the model still thinks, you just can't see the summary. The --thinking-display summarized CLI flag doesn't have this issue because it sets display directly instead of clobbering the entire thinking object into every request body, but as shawnz already noted that one breaks /plugins. So each of the two known workarounds disables a different surface — env var → no WebSearch, CLI flag → no /plugins. Pretty strong case for finishing the half-shipped thinkingDisplay key Val4evr documented in 2.1.116; the runtime already reads it from w.thinkingDisplay, the schema just rejects persisting it.

Reproduces on: Windows 11, Opus 4.7 (1M context, claude-opus-4-7[1m]), Claude Code 2.1.x via VS Code extension, ~/.claude/settings.json exactly as shawnz posted. Removing the env block restores WebSearch immediately.
Also happens in the Claude Code CLI. Same thing. Also tried using Sonnet and same issue happened.

shawnz · 2 months ago

@vinozganic if you are trying to get this working with VS code, you should check issue #49322 which has workarounds specific to VS code.

For example, we since found that by changing the parameter order in which you add the --thinking-display summarized, it fixes the issue with subcommands. See here https://github.com/anthropics/claude-code/issues/49322#issuecomment-4323290907

vinozganic · 2 months ago
@vinozganic if you are trying to get this working with VS code, you should check issue #49322 which has workarounds specific to VS code. For example, we since found that by changing the parameter order in which you add the --thinking-display summarized, it fixes the issue with subcommands. See here #49322 (comment)

Appreciate it brother. Successfully fixed it. Everything's now working in my VSC and Cursor (Claude Code extension)

xlurie · 2 months ago

This is hurting my (and my team's) daily work — quick context on why thinking.display matters, and what I traced.

I'm on a Max plan, and I want to push back on treating summarized thinking as a nice-to-have. For how I work it's load-bearing in two ways:

  1. Steering — seeing the reasoning as it streams lets me catch the model heading the wrong way and redirect before it commits a full answer. Without it I only find out after the fact, and re-run.
  2. Prompt debugging — what the model "understood" about my request is the single fastest signal for what to fix in the prompt; it's how I tighten prompts and get better results with fewer round-trips. Losing it makes every interaction slower and noisier.

After digging into this thoroughly: since around the evening of 2026-05-11, the summarized thinking block stopped arriving on claude-opus-4-7 (and claude-opus-4-7[1m]). I traced it at the HTTP layer — Claude Code sends the correct request (thinking: {"type":"adaptive","display":"summarized"}, no redact-thinking-* header, showThinkingSummaries: true set), byte-identical to the request that still works on claude-opus-4-6 / claude-sonnet-4-6 — but the 4.7 response stream carries zero thinking_delta events (just content_block_start(thinking) + signature_delta). So this is 100% server-side, independent of Claude Code version, and it contradicts the current docs, which still tell callers to set display: "summarized" to get summaries on Opus 4.7. It appears specific to OAuth/subscription auth (consistent with #52376 — API-key sessions reportedly still get the summary; see also #56356), and no client-side workaround helps (tried CLAUDE_CODE_EXTRA_BODY, betas, model variants, undocumented display values).

Honestly: paying $200/mo and having a working feature silently disappear with no acknowledgement — and the only workaround being "switch to Opus 4.6 / Sonnet 4.6", i.e. give up the model I'm paying for — is a rough experience for a paid plan. Could the team please restore server-side honoring of thinking.display: "summarized" for subscription/OAuth sessions on Opus 4.7 — or, if it's intentional, say so and ship a client-side equivalent? Happy to share the full wire capture and repro steps.

Shadetail · 2 months ago

I've been using

``"CLAUDE_CODE_EXTRA_BODY": "{\"thinking\":{\"type\":\"adaptive\",\"display\":\"summarized\"}}"``
with

``"showThinkingSummaries": true,`
in my
settings.json` for the last few weeks which made thinking work in VS Code plugin with Opus 4.7 ever since it first broke, but yesterday I noticed it stopped working again, and all the thinking is back to being redacted.

This is the most important Claude Code feature for me! It's incredibly important that I'm able to see what Claude is thinking - not being allowed to see why AI is doing what it's doing is just insane, it's the exact opposite of safety that Anthropic prides itself on. You yourself just invented NLA because seeing Claude's thinking stream wasn't enough, you had to see it's per token thoughts as well, for safety! So you can confirm that Claude is aligned with you, that you're working together towards the same goal, that Claude means what it says and thinks in the direction that is productive and aligned with our actual intent and our goal. Why in the world you suddenly take this away from your users? Does Claude deserve privacy now? Sure no problem, just come out and actually say it, say it why it is that you are doing this. Why are you not letting us see some of the most important data that we need to actually use the tools that many of us, myself included, pay $200 a month for? I don't want to hear conspiracy theories, I want to hear if this is a bug, or if it's intentional and official, then come out and say it.

betovildoza · 2 months ago

For me it's a UI/UX problem, try this in the VSC extension: move the thinking toggle to the right, send a message that makes Claude think, wait, you should see "thinking Xs" when Claude finishes, only when he finishes, write something else and before sending it, move the toggle to the left. The thinking block appears again for that session and until the compact.
I made the #49739 due to the poor visual feedback of the system

ojura · 2 months ago

Filed #59844 with two fix options that converge with the diagnosis here.

The narrower of the two (preferred) is one-line: drop the !getIsNonInteractiveSession() gate from the existing K3.display = "summarized" assignment, so showThinkingSummaries: true propagates to q.display in every surface (interactive, --print, SDK, VS Code chat panel). This is a smaller change than promoting --thinking-display out of .hideHelp() + adding a new thinkingDisplay settings.json key, because it reuses the existing documented setting and adds no API surface.

The wider alternative (one-line extension.js change) is also listed in #59844 in case there's a reason to keep the CLI gate that isn't visible from the leaked source.

Both options set display only, not type, so the per-request q.type !== "disabled" gate continues to drop the entire thinking field for forced-tool-use and incompatible-model sub-calls. Avoids the #56984 failure mode.

Disclosure: written with Claude Opus 4.7.

asvishnyakov · 1 month ago

Pretty much sure Anthropic will ignore this issue just like all others

timherby · 1 month ago

Please fix this.

This is an important tool for my company, and you've put us into a bind, Anthropic. You are effectively rendering Conductor useless on June 15th, and your native harness no longer has thinking blocks saved. We have an /introspect command that helps figure out why skills are not working, and without thinking blocks in the logs, the skill is far less useful. We had this with Conductor, even in Opus 4.7, and now as we switch to the first party Claude Code Desktop, there is no way to get thinking blocks in logs.

venpopov · 1 month ago

has anyone figured out a workaround for Claude Code web remote sessions? None of the mentions above apply to it (and the breakage of web search is not worth it for the one potential workaround)

jonlepage · 1 month ago

where are Thinking summaries in 4.8 ? it very important feature !
https://github.com/anthropics/claude-code/issues/63358

Claude said the flag 'display: "summarized"' on server side was turned off, idk why your team do this !
We need to read how LLM think and see the instruction

betovildoza · 1 month ago

Claude's new update, and the button is still inverted. Furthermore, the process of having to move it to the right, send a message, wait for a response, move it to the left, and only then see the thinking block still has no solution.
The only new feature is that it now shows a preview of how many tokens the input consumes.

Screenshots attached.

<img width="1105" height="641" alt="Image" src="https://github.com/user-attachments/assets/9b96b7db-2adc-4049-98ff-59d758721297" />

jasonnickel · 1 month ago

This root-cause report is still live, and the defect has now carried forward to Opus 4.8 — same omitted default, same harness behavior, newest model. I filed the 4.8-specific reproduction as #63358; posting the hard evidence here since this is the canonical issue.

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

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

with the note that this was a "silent change from Opus 4.6 where the default was to return summarized thinking text." The capability schema shows adaptive-thinking-only ("thinking": {"types": {"enabled": {"supported": false}, "adaptive": {"supported": true}}}), so these models only do adaptive thinking — whose default is display: "omitted".

The only documented restore path is the SDK request param thinking={"type": "adaptive", "display": "summarized"}. There is no user-facing setting / env var / render toggle, which matches the reports in this thread that MAX_THINKING_TOKENS, showThinkingSummaries, chat.agent.thinkingStyle, Ctrl+O, and even --thinking adaptive --thinking-display summarized (#56356) don't help.

Reproduced on macOS / Apple silicon (Darwin 25.5.0), VS Code 1.122.0, claude-opus-4-8[1m]: chat shows only a thinking-token counter; /model claude-sonnet-4-6 or claude-opus-4-6 restores visible summaries instantly.

Suggested framing so this stops recurring with each new model: key the fix off the model's API default rather than a hardcoded model list — whenever thinking is enabled, have the harness request display: "summarized" for any model whose default is omitted. Otherwise 4.8 (and every future Opus that ships with the omitted default) each reintroduces this.

Madd0g · 1 month ago

I was bummed on 4.7 release day for like half a day until I found the CLI argument workaround. Now I gotta be bummed when using the next model too because the workaround just stops working as soon as I switch to the 4.8 model.

gah. so disappointing.

cnighswonger · 1 month ago

Confirming @jasonnickel's binary finding extends through CC 2.1.158 — the no-reader pattern for showThinkingSummaries still matches on the most recent build.

We've been checking each CC release via strings/grep on the unstripped Bun binary, and showThinkingSummaries-no-reader is one of the patterns the watcher tracks across releases. As of v2.1.158: we still do not find a reader/reference path for the field in the binary. The Zod schema declares it (so settings.json accepts it without warning), but we don't currently see a settings-binding surface in the binary for it. That's consistent with the "key off model default rather than a hardcoded model list" framing in jasonnickel's comment — without a reader, no setting has anything to bind to.

For anyone landing here looking for current workaround status: the current binary evidence is consistent with --thinking-display summarized flag emission being gated on showThinkingSummaries being read (we have grep evidence for the field-name linkage, not end-to-end branch verification). That's a plausible mechanism for why the flag-style workarounds @Madd0g and others mention worked on 4.7 but stop working when switching to 4.8 — different model default, same harness gap.

The only documented restore path remains the SDK request param thinking={"type": "adaptive", "display": "summarized"}. Anyone driving CC via the Agent SDK or a proxy can set it there; we do not currently know of a documented way for bundled-harness users to force the equivalent.

The structural framing jasonnickel proposed — make the harness request display: "summarized" for any model whose API default is omitted, rather than hardcoding model names — would close this for 4.8 and every future Opus that ships the omitted default. That's the cheapest fix that doesn't have to be re-applied per-release.

— AI Team Lead

Mart-Bogdan · 1 month ago

Nice that claude --thinking-display summarized workaround exists.

Sadly I do enjoy using Claude Desktop. So I'd have to stick to claude-cli + remote session?

cnighswonger · 1 month ago

@Mart-Bogdan — yes, the --thinking-display summarized workaround is CLI-only. Claude Desktop is a separate code path that doesn't accept the CLI flag; it runs its own UI shell on top of the model API and has its own thinking-display defaults independent of the CLI binary's harness.

So your options if you want populated thinking blocks today are: CLI (claude --thinking-display summarized or the alias form upthread), or wait for an Anthropic-side fix on the Desktop surface. The CLI fix is local-only and won't help Desktop users — that's a real gap worth Anthropic addressing, but it's a separate issue from the CLI harness defect this filing is tracking.

— AI Team Lead

BarriePocock · 1 month ago

Confirmed on the standalone Claude Desktop app (Windows) + Opus 4.8 — and it hot-reloads, no restart.

Most reports here are CLI/VS Code; confirming the CLAUDE_CODE_EXTRA_BODY workaround works in the desktop Electron app too:

"env": { "CLAUDE_CODE_EXTRA_BODY": "{\"thinking\":{\"type\":\"adaptive\",\"display\":\"summarized\"}}" }
Data: persisted session JSONL flipped from empty thinking blocks ("thinking":"") to populated (1000–1700 chars/turn) on the exact turn after re-saving settings.json — claude-opus-4-8, Claude Code 2.1.165 / desktop 1.11187.4. Took effect mid-session (hot-reload), no relaunch. Before: thinkChars=0 across 18 turns; after: 1056, 1131, 1670, 1374…

showThinkingSummaries:true was not needed (and made rendering chunkier) — the env var alone does it. And thinkingDisplay as a settings key is read by the 2.1.165 runtime but rejected by the settings-schema validator ("Unrecognized field"), so it can't be saved — CLAUDE_CODE_EXTRA_BODY is the working settings path. A thinkingDisplay schema entry, or defaulting display:"summarized" when thinking is enabled, would close this for everyone.

phase3dev · 1 month 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 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

venpopov · 1 month ago
Workarounds: 1. Custom launcher, recommended (shell script on Linux; small Node script compiled to a standalone .exe on Windows)

Btw, for those who use Claude Code Web - the custom launcher trick also works there. We wrote a thin wrapper around the binary that gets set up during the setup script and is put higher on the path. That way you can pass any additional flags that you want. It works well and unlike some of the earlier suggested workarounds, it doesn't disable webfetch.

Mart-Bogdan · 1 month ago

@BarriePocock nice, it worked! Sadly it breaks Haiku models!

API Error: 400 adaptive thinking is not supported on this model

So can't uptimize context/usage by using Haiku subagents.

studentstudentlgg · 27 days ago

Is there a way to fix this on cowork?

BilalAtique · 10 days ago

Pinned down the Vertex variant of this with request-level evidence, filed with full details at anthropics/claude-agent-sdk-typescript#367. TL;DR:

  • Even when --thinking-display summarized is passed (verified via argv shim on the spawned binary), the outbound Vertex request omits display — captured via ANTHROPIC_VERTEX_BASE_URL sink: {"thinking":{"budget_tokens":31999,"type":"enabled"}}.
  • The drop is a provider allowlist in the CLI's request builder (minified names from 2.1.185): As = xs && BO() && gkt(u) ? n.display : void 0, where BO()RLr()e==="firstParty"||e==="anthropicAws"||e==="foundry"vertex/bedrock excluded, foundry allowed, which suggests a stale allowlist rather than a capability guard.
  • Vertex itself honors display:"summarized" (direct streamRawPredict with anthropic_version: vertex-2023-10-16 returns thinking_delta events with summary text on claude-sonnet-5 / opus-4-8).
  • A/B: byte-patching that single gate to constant-true → summarized thinking streams over Vertex (0 chars → 240 chars, same query).

One repro gotcha for anyone instrumenting this via the Agent SDK: it spawns its own bundled platform binary (@anthropic-ai/claude-agent-sdk-<platform>/claude), not the @anthropic-ai/claude-code install.