[BUG] Bedrock/Vertex/Mantle: thinking.display never reaches the request body; client-side (server honors the field), at least two dropping points incl. the provider gate; follow-up to #67729 and #79052
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet (all prior reports of this class are closed: #67729 stale, #79052 stale, #71599/#79060/#86959 duplicates)
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
On the bedrock, vertex, and mantle providers, thinking.display never
reaches the request body. Thinking blocks arrive signature-only with an emptythinking field on every model whose server-side default is omitted
(Sonnet 5, Opus 4.7+, Claude 5 family). No client configuration can override
it: the explicit --thinking-display summarized flag parses and is accepted,showThinkingSummaries: true resolves correctly, and both are then discarded
before the request is built. All three provider APIs accept and honor the
field when sent directly (confirmed in #67729 via AnthropicBedrock SDK and
boto3, and in #79052 via request capture on Vertex).
This is the same defect previously reported as #67729 (Bedrock, 2.1.170) and
#79052 (Vertex, 2.1.215, labeled reproduced and regression). Both were
closed by the stale bot without a fix, with #71599, #79060 and #86959
deduplicated into them. It is still present in 2.1.287.
New information beyond those reports: the root cause, read from the 2.1.287
bundle (minified names are build-specific):
// gate A: updated at some point to include mantle:
function H$(e=Me()){return e==="firstParty"||M$(e)||e==="foundry"||e==="mantle"}
// gate B: never updated; no bedrock, no vertex, no mantle:
function Boe(){let e=Me();return e==="firstParty"||M$(e)||e==="foundry"}
function M$(e=Me()){return e==="anthropicAws"||e==="anthropicGoogleCloud"}
function K4(){return a.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS||UD()}
function Im(){return Boe()&&!K4()}
function LGn(e){return Im()&&$Sn(e)} // $Sn = per-model interleaved-thinking check
// thinking-config assembly:
// zm = Um && LGn(We); Ih = !zm ? void 0 : r.display
// -> when Boe() is false, `display` is silently dropped from the request
Everything upstream of gate B behaves correctly: the display value resolves
to "summarized" from the flag (Mqo: {display:e, source:"flag"}) or fromshowThinkingSummaries (NSn), the model checks pass ($Sn returns true on
these providers for current models), and H$ passes. Attachment then dies atIm() because Boe() has no bedrock/vertex/mantle arm. One predicate
explains every provider variant reported across the five issues above, and
explains why the fix that closed #77460 (which updated H$) did not resolve
them.
What Should Happen?
thinking.display should be forwarded on providers whose APIs accept it (Bedrock, Vertex and Mantle all do), exactly as the same command does on the
first-party API. The fix appears to be one token per provider in Boe (or
reusing H$ there, if the remaining delta between the two gates is
unintentional).
Error Messages/Logs
No error is emitted; the flag and setting are silently ignored.
Representative measurements on 2.1.287, mantle provider, default model,
prompt chosen to reliably trigger thinking:
baseline: thinking_len=0 sig_len=900
--thinking-display summarized: thinking_len=0 sig_len=928
interactive session with showThinkingSummaries: true: identical
(thinking blocks present and signed, zero chars of text)
Signature size grows with --effort, so reasoning is happening and being
billed; only the text is omitted, exactly as if display:"omitted" was sent.
Steps to Reproduce
PROMPT="Find all three-digit numbers whose digits sum to 15 and whose first digit is twice the third. Reason step by step."
# (A) Bedrock: prints 0
CLAUDE_CODE_USE_BEDROCK=1 ANTHROPIC_MODEL=<any sonnet-5/opus-4-7+ bedrock profile> \
claude -p "$PROMPT" --output-format stream-json --verbose --max-turns 1 \
--thinking-display summarized \
| jq -r 'select(.type=="assistant") | .message.content[] | select(.type=="thinking") | (.thinking|length)'
# (B) Same command, first-party: prints a positive length
# (C) CLAUDE_CODE_USE_VERTEX=1: prints 0 (see #79052)
# (D) CLAUDE_CODE_USE_MANTLE=1: prints 0
Claude Model
Not sure / Multiple models (any model whose display default is omitted)
Is this a regression?
Yes for Vertex per #79052 (worked <= 2.1.140); #67729 suggests the Bedrock
path may never have forwarded it.
Claude Code Version
2.1.287 (lineage: 2.1.170 -> 2.1.174 -> 2.1.207 -> 2.1.215 -> 2.1.287 all affected)
Platform
AWS Bedrock / Google Vertex / Mantle
Operating System
Linux (Ubuntu 24.04); prior reports on macOS - not platform-specific
Additional Information
- Impact: on these providers (the standard enterprise setups), thinking is
billed on every request while being unobservable by any configuration:
no agent observability or tracing of reasoning is possible without
bypassing the CLI for direct API calls.
- Previous reports of this exact defect were closed by the stale bot while
carrying has repro / reproduced labels (#67729, #79052). Given the
root cause above is now located to a single predicate, requesting this one
be triaged rather than aged out; happy to re-verify a fix on any build.
---
UPDATE (2026-10-02, same day): deeper than the gate; server side confirmed working
After filing, we validated the analysis with local same-length byte patches and by capturing the CLI's outgoing request bodies (ANTHROPIC_BEDROCK_MANTLE_BASE_URL pointed at a local logging forwarder). Corrections and new findings:
- Gate B is a defect but not the whole story. With gate B widened to include
mantle, and even withdisplayforced to a literal at the located thinking-assembly site (Zc={type:"adaptive",display:...}), the wire body still carries bare{"type":"adaptive"}. A same-length marker rename of thedisplaykey at that site never appeared on the wire either, for-por interactive sessions. So the request builder actually serving live sessions on the mantle path is a different code path that ignores the session display config entirely; we could not locate it by source inspection (every{type:"adaptive",display:X}construction and both thinking rebuild switches in the bundle are accounted for and are not it).
- Additional
-pdefect.--thinking-display summarizedresolves into the session config at the entrypoint, butdisplayExplicitis never set on that path, so the non-interactive downgrade function (which forcesdisplay:"omitted"for non-interactive sessions unless the display was explicit) cancels the explicit flag. Interactive sessions resolve display fromshowThinkingSummarieswith no provider gate involved, and still produce bare{"type":"adaptive"}on the wire (captured).
- The server honors the field. Hand-signed SigV4 request pairs to the mantle gateway (
/anthropic/v1/messages), identical except for the field: control{"type":"adaptive"}returns a thinking block with empty text and a signature;{"type":"adaptive","display":"summarized"}returns summarized thinking text. A local re-signing proxy that injectsdisplayinto otherwise-unmodified CLI requests restores working thinking summaries end to end through the unmodified CLI (verified:thinking_len=398on a prompt that previously returned 0). The entire failure is client-side request construction.
Net: on 2.1.287 the bedrock/mantle path has at least two independent dropping points (the provider gate reported above, plus whatever builds the wire body for live sessions), and the -p flag path has the displayExplicit regression. Happy to run any diagnostic build or verbose flag against this setup to help pin the wire-builder.
3 Comments
This is happening to me and its blocking me from upgrading to the 5.x models as they wont accept prompting to explain thinking and this bug means I can't even see the summaries
This issue needs attention as its pending for a long time and it blocks our proper usage of the models.
#677
Confirming this is still present in 2.1.293 (Agent SDK 0.3.293 native binary) on Bedrock,
global.anthropic.claude-opus-5-5, us-west-2.claude -p ... --thinking adaptive --thinking-display summarized --effort max→ thinking block is signature-only (0 chars). Same forglobal.anthropic.claude-opus-4-7.thinking: { type: "adaptive", display: "summarized" }andshowThinkingSummaries: true(programmatic settings) are dropped the same way.bedrock-runtime invoke-modelwith"thinking": {"type":"adaptive","display":"summarized"}returns summarized thinking for Opus 5.5; with"omitted"it's empty. So Bedrock honors the field.bedrockarm.Impact: ACP clients built on
@agentclientprotocol/claude-agent-acpcan't show reasoning for any current Opus model on Bedrock.