Vertex: `thinking.display` dropped from request body under CLAUDE_CODE_USE_VERTEX=1 — Sonnet 5 thinking text invisible on Vertex
Summary
When CLAUDE_CODE_USE_VERTEX=1, the CLI omits the thinking.display field from the request body it sends to Vertex AI, even when --thinking-display summarized is passed. The identical invocation against the first-party API (api.anthropic.com) includes "display": "summarized".
On models where thinking.display defaults to "omitted" — Claude Sonnet 5, Opus 4.7+ — this makes thinking text unrecoverable on Vertex: thinking blocks arrive with an empty thinking field (or no block at all when the model skips thinking). Sonnet 4.6 masks the bug because its server-side default is "summarized", so the dropped parameter has no visible effect there. The result is a confusing asymmetry: thinking traces show up for Sonnet 4.6 on Vertex and for Sonnet 5 on the direct API, but silently disappear for Sonnet 5 on Vertex.
Vertex itself supports the parameter (see confirmation below), so this is purely the CLI's Vertex request builder dropping the field.
Environment
- Claude Code 2.1.215 (current
latestandnexton npm at time of filing) - macOS (darwin 25.5.0)
- Model:
claude-sonnet-5on Vertex AI,globalendpoint
Reproduction
Run the same command twice, once per provider, behind any HTTP capture proxy (ANTHROPIC_BASE_URL / ANTHROPIC_VERTEX_BASE_URL pointed at a local logging forwarder), and diff the captured request bodies.
Direct API:
claude -p "How many rs are in strawberry? Reason briefly." \
--model claude-sonnet-5 --thinking-display summarized \
--output-format stream-json --verbose
Captured body sent to POST /v1/messages?beta=true:
"thinking": {"type": "adaptive", "display": "summarized"}
Vertex:
CLAUDE_CODE_USE_VERTEX=1 ANTHROPIC_VERTEX_PROJECT_ID=<project> CLOUD_ML_REGION=global \
claude -p "How many rs are in strawberry? Reason briefly." \
--model claude-sonnet-5 --thinking-display summarized \
--output-format stream-json --verbose
Captured body sent to POST /v1/projects/<project>/locations/global/publishers/anthropic/models/claude-sonnet-5:streamRawPredict:
"thinking": {"type": "adaptive"}
The display field is gone. Everything else (output_config: {"effort": "high"}, max_tokens, messages) carries over identically.
Expected
--thinking-display summarized should be forwarded on the Vertex path the same way it is on the first-party path.
Actual
display is silently dropped on the Vertex path only. On Sonnet 5 / Opus 4.7+ the thinking summary is therefore never visible via Vertex — while the user is still billed for the full thinking tokens (usage.output_tokens_details.thinking_tokens is populated).
Confirmation that Vertex supports the field
A raw request to the same Vertex model with display: "summarized" returns a populated thinking summary, so the endpoint honors the parameter when it actually receives it:
curl -X POST \
"https://aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/global/publishers/anthropic/models/claude-sonnet-5:rawPredict" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"anthropic_version": "vertex-2023-10-16",
"max_tokens": 4000,
"thinking": {"type": "adaptive", "display": "summarized"},
"messages": [{"role": "user", "content": "How many rs are in strawberry? Reason it out."}]
}'
Response contains:
{"type": "thinking", "thinking": "Spelling out \"strawberry\" and counting the letters, I find there are 3 R's in the word—appearing in positions 3, 8, and 9.", "signature": "..."}
with usage.output_tokens_details.thinking_tokens: 111.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗