Subagents & structured-output requests 400 against third-party endpoints requiring a `thinking` field (CC omits `thinking` on those requests)

Open 💬 0 comments Opened Jun 18, 2026 by Zane-0x5a

Subagents (and structured-output requests) fail with 400 against third-party Anthropic-compatible endpoints that require a thinking field — CC omits thinking on those requests

Summary

When Claude Code is pointed at a third-party Anthropic-compatible endpoint via ANTHROPIC_BASE_URL whose model requires a thinking field on every /v1/messages request (Moonshot's kimi-k2.7-code does), the main interactive thread works, but subagents fail immediately with:

API Error: 400 invalid thinking: only type=enabled is allowed for this model

The subagent produces 0 tool uses — its transcript is two lines: the spawn prompt, then the 400. The same failure also hits CC's session-title generation and other structured-output (output_config.format) requests.

Root cause (confirmed by request capture): CC 2.1.181 omits the thinking field on structured-output and certain subagent-spawn requests. The upstream model rejects any /v1/messages request that lacks thinking. No thinking-related env var fixes it, because those requests never pass through CC's thinking-injection path.

Environment

  • Claude Code 2.1.181 (native install, Windows 11)
  • ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic (Moonshot, Anthropic-compatible)
  • Model: kimi-k2.7-code via ANTHROPIC_MODEL and ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL
  • This is a "firstParty"-classified provider (custom base URL, no CLAUDE_CODE_USE_BEDROCK/VERTEX/...).

Repro

  1. Configure CC against an Anthropic-compatible endpoint whose model requires thinking on every request (Moonshot kimi-k2.7-code).
  2. Start an interactive session — normal chat turns work.
  3. Trigger a subagent (e.g. a workflow that spawns Task/Agent subagents, or any create-style skill that fans out).
  4. The subagent dies instantly with 400 invalid thinking: only type=enabled is allowed for this model, 0 tool uses.

Evidence (captured outbound request bodies)

Using a local pass-through proxy as ANTHROPIC_BASE_URL, the actual requests CC sends are:

  • Normal chat turn (works):

``json
{ "model": "kimi-k2.7-code", "thinking": {"type":"adaptive"}, "output_config": {"effort":"max"}, ... }
``

  • Session-title / structured-output request (400s):

``json
{ "model": "kimi-k2.7-code", "output_config": {"effort":"max","format":{"type":"json_schema", ...}}, ... }
`
— note: **no
thinking` field at all**.

  • Subagent spawn first request (400s): same shape — thinking absent.

Direct tests against the upstream confirm the rule (the model accepts a request iff it carries thinking; the effort value is irrelevant):

| Request body | Upstream response |
|---|---|
| thinking:{type:"enabled",budget_tokens:1024} | ✅ 200 |
| thinking:{type:"adaptive"} (no effort) | ✅ 200 |
| thinking:{type:"adaptive"} + output_config:{effort:"max"} | ✅ 200 |
| output_config:{effort:"max"}, no thinking | ❌ 400 only type=enabled is allowed |
| empty (no thinking, no effort) | ❌ 400 only type=enabled is allowed |

So the upstream's only type=enabled is allowed message is misleading: it actually means "no thinking field was sent." CC's structured-output / subagent requests omit thinking, hence the 400.

Why no env var fixes it

Tested ineffective (the failing requests don't go through the thinking-injection path):

  • MAX_THINKING_TOKENS=0 and =8192
  • CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1 (binary shows it's gated to model names containing opus-4-6/sonnet-4-6, so it's a no-op for any other model)
  • ANTHROPIC_DEFAULT_*_MODEL_SUPPORTED_CAPABILITIES set to "", adaptive_thinking, !adaptive_thinking, interleaved_thinking, !effort,!adaptive_thinking
  • CLAUDE_CODE_DISABLE_THINKING=1 (removes thinking from chat turns too → makes the main thread fail the same way)
  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1

Suggested fix

When the active provider/model requires a thinking field, CC should include thinking on all /v1/messages requests it builds — including structured-output (output_config.format) requests and subagent-spawn requests — not only on regular assistant turns. Even a minimal thinking:{type:"adaptive"} (or {type:"enabled", budget_tokens:N}) on those requests resolves it.

Alternatively, expose a documented per-model override that forces a chosen thinking shape on every request to that model (the existing *_SUPPORTED_CAPABILITIES knob does not currently affect these request paths).

Workaround

A tiny local proxy that injects thinking:{type:"adaptive"} into any /v1/messages request lacking it makes both the main thread and subagents work end-to-end against kimi-k2.7-code.

View original on GitHub ↗