Skip to main content

Fix Claude Code 400: thinking type should be enabled or disabled

Your endpoint rejects the adaptive thinking type Claude Code sends. Set CLAUDE_CODE_DISABLE_THINKING=1; the adaptive switch won't help GLM or DeepSeek IDs.

LaoZhang AI TeamPublished13 min read
On this page
Claude Code sends the adaptive thinking type, the custom endpoint accepts only enabled or disabled and returns a 400, and CLAUDE_CODE_DISABLE_THINKING=1 is the fix

API Error: 400 thinking type should be enabled or disabled comes from the Anthropic-compatible endpoint you set in ANTHROPIC_BASE_URL, not from Anthropic. Claude Code sent "thinking": {"type": "adaptive"}, and that endpoint only accepts enabled or disabled. Your key, your quota and the model itself are fine.

The fix that worked for every model ID in a test with Claude Code 2.1.306 is CLAUDE_CODE_DISABLE_THINKING=1: add it to the env block of ~/.claude/settings.json and start a new session. Claude Code then leaves the thinking field out of the request. The fix that circulates most, CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1, only changes requests for Opus 4.6 and Sonnet 4.6. In the same test, GLM and DeepSeek model IDs kept sending adaptive with it set and kept failing. If you need thinking to stay on with one of those models, a modelOverrides entry that maps a dated Claude 4.5 ID to your model ID made Claude Code send enabled with a budget instead (details below).

What "thinking type should be enabled or disabled" means

The endpoint understood your request and refused one field in it. Anthropic's Messages API has two ways to ask for thinking: the older {"type": "enabled", "budget_tokens": N} with a fixed budget, and {"type": "adaptive"}, where the model decides how much to think. Many compatible endpoints only implemented the first one plus disabled. SiliconFlow's Anthropic-format Messages API reference, for example, lists disabled and enabled (with budget_tokens required) and no adaptive value as of October 21, 2026.

Claude Code decides what to put in thinking by matching the model ID against patterns it knows, according to the Claude Code model configuration docs. On 2.1.306, both current Claude IDs and IDs it doesn't recognize at all, such as Pro/zai-org/GLM-5, got adaptive by default. That is why the error usually appears right after a Claude Code update or after switching models: the request changed, the endpoint didn't.

The same rejection shows up with different wording depending on who answers. These are dated community reports, and any of these providers may have changed since:

Message you seeReported withReport
thinking type should be enabled or disabledSiliconFlow, including Pro/zai-org/GLM-5cc-switch issue #1489 (March 13, 2026), jetbrains-cc-gui issue #801 (March 27, 2026)
Only 'enabled' and 'disabled' are supported for thinking; 'adaptive' is not supported.Alibaba Cloud Coding Plancc-switch issue #1173 (February 28, 2026)
'type' must be in ["enabled", "disabled", "auto"]SenseNova, Claude Code v2.1.220cc-switch discussion #5864 (July 29, 2026)
adaptive thinking is not supported on this modelClaude Haiku 4.5 on Vertex AI behind a LiteLLM /v1/messages pass-throughLiteLLM issue #31030 (June 22, 2026)

The last row is Anthropic's own wording for a Claude model that supports only extended thinking. The Claude Platform thinking troubleshooting page gives the remedy for that case: send enabled with a budget instead of adaptive.

The fix: add CLAUDE_CODE_DISABLE_THINKING=1 to settings.json

Open ~/.claude/settings.json and add the variable to its env block. If you configured your endpoint through that file, the block already exists and holds ANTHROPIC_BASE_URL, so add one line there rather than creating a second env key. Values in env are strings:

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://your-endpoint.example.com",
    "ANTHROPIC_AUTH_TOKEN": "your-api-key",
    "ANTHROPIC_MODEL": "your-model-id",
    "CLAUDE_CODE_DISABLE_THINKING": "1"
  }
}

Keep any other keys you already have (permissions, model, plugins) in the same top-level object. If you set your endpoint in the shell instead, export CLAUDE_CODE_DISABLE_THINKING=1 before running claude does the same thing.

Then exit Claude Code and start it again, because the env block is read at startup. A quick check is claude -p "Reply with OK": you should get a reply instead of the 400. If you want the base setup explained (ANTHROPIC_BASE_URL, keys, model pins), see Claude Code API Configuration: Keys, Settings, Models, and Gateways.

The Claude Code environment variable reference describes CLAUDE_CODE_DISABLE_THINKING as "a compatibility option for proxies and gateways that reject the parameter." In the test below it removed the field for every model ID tried, worked from the settings env block as well as from the shell, and won over a saved alwaysThinkingEnabled: true.

Two other settings produce the same request, but only for some model IDs:

  • MAX_THINKING_TOKENS=0 removed the field for a GLM ID, but had no effect on claude-opus-5-5, which kept sending adaptive.
  • Thinking off in /config, saved as alwaysThinkingEnabled: false, behaved the same way: fixed for GLM, ignored for claude-opus-5-5. The docs say Opus 5.5, Sonnet 5.5, Haiku 5.5 and Fable models show "Thinking can't be turned off" and ignore both settings.

The session shortcut, Option+T on macOS and Alt+T on Windows and Linux, is the per-session version of the /config switch. It wasn't part of the test, and it can't help with 5.5 or Fable model IDs for the same reason.

CLAUDE_CODE_DISABLE_THINKING only touches thinking. Claude Code still sent "output_config": {"effort": "high"} with the field removed. If your endpoint then rejects something about effort, that is a separate message about a separate field.

Why CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1 didn't fix it

That variable was never meant for non-Claude models. The env var reference says it disables adaptive reasoning "on Opus 4.6 and Sonnet 4.6" and falls back to the fixed budget from MAX_THINKING_TOKENS. It has no effect on Fable models, Sonnet 5 and later, Haiku 5.5, or Opus 4.7 and later. It says nothing about IDs like Pro/zai-org/GLM-5 or deepseek-v4-pro, and in the test those IDs kept sending {"type": "adaptive"} with the variable set. Adding MAX_THINKING_TOKENS=8000 didn't change that either: the docs say a positive value is ignored on adaptive models unless the adaptive switch applies.

The variable does work where the docs say it does. With claude-sonnet-4-6 it turned the request into {"type": "enabled", "budget_tokens": 31999} and the call went through. So advice that "this fixed it for me" can be accurate for someone routing a Claude 4.6 ID and still be wrong for you.

The model-capability variables don't help through a gateway either. The model configuration docs say ANTHROPIC_DEFAULT_*_MODEL_SUPPORTED_CAPABILITIES takes effect on Bedrock, Google Cloud's Agent Platform and Microsoft Foundry, while through an ANTHROPIC_BASE_URL gateway only the _NAME and _DESCRIPTION variables apply. Declaring thinking, effort,thinking or effort for a GLM ID pinned to the sonnet slot left the request at adaptive every time.

A quick way to tell which group your model is in: Claude Code 2.1.306 printed this line for every unrecognized ID in the test.

Claude Code doesn't recognize the model "Pro/zai-org/GLM-5", so it assumes a context window of 200k tokens.

If you see it for your model, the adaptive switch won't change your request. CLAUDE_CODE_DISABLE_THINKING=1 is the quickest client-side fix, and modelOverrides is the one that keeps thinking on.

Test results: what Claude Code 2.1.306 sends for each model ID and setting

These results show what Claude Code puts in the request, not how any provider answers today. The test ran on October 21, 2026: Claude Code 2.1.306 on macOS, one claude -p "Reply with OK" per case with a fresh config directory, and ANTHROPIC_BASE_URL pointed at a local mock endpoint. The mock logged every request body and answered 400 thinking type should be enabled or disabled whenever thinking.type was anything other than enabled or disabled. It is not SiliconFlow or any other real provider, and its error body was written to match the message, so a real provider's body may differ. No requests left the machine.

Model ID sentSettingthinking in the requestMock result
Pro/zai-org/GLM-5none{"type": "adaptive", "display": "omitted"}400
deepseek-v4-prononeadaptive400
Pro/zai-org/GLM-5CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1adaptive400
Pro/zai-org/GLM-5MAX_THINKING_TOKENS=8000adaptive400
Pro/zai-org/GLM-5 via the sonnet slotwith or without _SUPPORTED_CAPABILITIES (4 cases)adaptive400
Pro/zai-org/GLM-5MAX_THINKING_TOKENS=0not sent200
Pro/zai-org/GLM-5alwaysThinkingEnabled: falsenot sent200
Pro/zai-org/GLM-5CLAUDE_CODE_DISABLE_THINKING=1 (shell, settings env, or with alwaysThinkingEnabled: true)not sent200
claude-sonnet-4-6noneadaptive400
claude-sonnet-4-6CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1{"type": "enabled", "budget_tokens": 31999}200
claude-opus-4-6adaptive switch + MAX_THINKING_TOKENS=10000enabled, budget 10000200
claude-sonnet-4-5, claude-haiku-4-5noneenabled, budget 31999200
haiku alias, resolved to claude-haiku-5-5noneadaptive400
claude-opus-5-5MAX_THINKING_TOKENS=0 or alwaysThinkingEnabled: falseadaptive400
claude-opus-5-5, and sonnet alias resolved to claude-sonnet-5-5CLAUDE_CODE_DISABLE_THINKING=1not sent200
Pro/zai-org/GLM-5modelOverrides from claude-sonnet-4-5-20250929, selected with ANTHROPIC_MODEL (shell or settings env)enabled, budget 31999200
Pro/zai-org/GLM-5same override + MAX_THINKING_TOKENS=8000enabled, budget 8000200
deepseek-v4-promodelOverrides from claude-haiku-4-5-20251001enabled, budget 31999200
claude-sonnet-4-5 (override not applied)modelOverrides keyed on the undated claude-sonnet-4-5enabled, budget 31999200, but sent to the wrong model name
Pro/zai-org/GLM-5modelOverrides from claude-sonnet-5-5adaptive400

The table covers 30 of the 31 runs, counting one repeat of the GLM default case. The remaining run tried a different model-picker setting whose configuration couldn't be confirmed, so it isn't listed.

Matrix of what Claude Code 2.1.306 sent for vendor, Claude 4.6, Claude 4.5 and Claude 5.5 model IDs under each setting: only CLAUDE_CODE_DISABLE_THINKING=1 cleared the 400 for both vendor and 5.5 IDs

A few details that matter when you read your own logs:

  • After the first 400, Claude Code sent the same request once more with one fewer beta header, then showed the error. Your provider's dashboard may log two rejected calls per prompt.
  • The opus, sonnet and haiku aliases resolved to 5.5 IDs on this version. If your gateway maps those names to an older Claude model, that older model receives an adaptive request it may not accept. LiteLLM issue #31030 describes this situation.
  • With CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1 on claude-opus-4-6, Claude Code printed a notice that thinking.type=enabled is deprecated for that model. The call still went through.

Check whether your endpoint accepts adaptive with curl

Run two requests that differ only in thinking, and you know whether this is the error you have. Use the same base URL, key and model ID as in Claude Code. Use the auth header your provider documents. Claude Code itself sends Authorization: Bearer when you set ANTHROPIC_AUTH_TOKEN; some providers expect x-api-key instead.

bash
BASE="https://your-endpoint.example.com"   # your ANTHROPIC_BASE_URL, no trailing slash
KEY="your-api-key"
MODEL="your-model-id"

# 1) adaptive, as Claude Code sends it
curl -sS "$BASE/v1/messages" \
  -H "Authorization: Bearer $KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"'"$MODEL"'","max_tokens":2048,"thinking":{"type":"adaptive"},"messages":[{"role":"user","content":"Reply with OK"}]}'

# 2) enabled with a fixed budget (budget_tokens must stay below max_tokens)
curl -sS "$BASE/v1/messages" \
  -H "Authorization: Bearer $KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"'"$MODEL"'","max_tokens":2048,"thinking":{"type":"enabled","budget_tokens":1024},"messages":[{"role":"user","content":"Reply with OK"}]}'

How to read the two answers:

Request 1 (adaptive)Request 2 (enabled)What it tells you
400 with the thinking-type message200The endpoint accepts thinking but not adaptive. Fix it in Claude Code: remove the field, or keep thinking on with modelOverrides. A gateway rewrite also works.
400400Something else is wrong too. Run it once more with no thinking field at all; if that also fails, look at the model ID, key or path first.
200200This endpoint accepts adaptive for this model now. If Claude Code still fails, the rejection comes from another hop, such as a gateway forwarding to an older model, or from a different field.

Does turning thinking off stop the model from reasoning?

Not necessarily. Through a custom endpoint, the settings that switch thinking off don't send {"type": "disabled"}. Turning thinking off in /config, MAX_THINKING_TOKENS=0 and CLAUDE_CODE_DISABLE_THINKING=1 all produced the same request in the test: one with no thinking field at all.

What happens next is up to the provider. The env var reference says omitting the parameter "means the model may still think" on models that think by default. One user in cc-switch issue #1489 reported that SiliconFlow's Anthropic endpoint thinks by default, so responses still contained reasoning after thinking was switched off in Claude Code. That is a single report, not a provider guarantee. For Opus 5.5, Sonnet 5.5, Haiku 5.5 and Fable models, Anthropic's docs say thinking can't be turned off at all.

So "I turned thinking off and lost reasoning quality" and "I turned thinking off and it still reasons" can both be true. The difference is the provider's default, not the Claude Code setting. If you need to know, check your provider's docs for what the model does when thinking is absent.

How to keep thinking on with GLM, DeepSeek or a Claude 4.x model

Claude Code sends enabled with a budget only when the model it selects is one it treats as a fixed-budget model: Claude 4.5 IDs, or Opus and Sonnet 4.6 with the adaptive switch. A vendor ID set directly in ANTHROPIC_MODEL always got adaptive in the test. You can still keep thinking on for a vendor model in two ways: make Claude Code select a Claude 4.5 ID and rename it on the way out with modelOverrides, or rewrite the field in a gateway.

Your setupWhat to changeRequest the endpoint gets
Vendor model ID (GLM, DeepSeek, Qwen…) and you can live with the provider's defaultCLAUDE_CODE_DISABLE_THINKING=1 in Claude CodeNo thinking field
Vendor model ID and you need explicit thinkingmodelOverrides from a dated Claude 4.5 ID to your model ID (below)enabled with a budget, under your model ID (mock-tested)
Vendor model ID, and you'd rather fix it outside Claude CodeA gateway or proxy that rewrites adaptive to enabled with a budget, or a provider that accepts adaptiveWhatever the gateway writes
claude-opus-4-6 or claude-sonnet-4-6 behind a gatewayCLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1, optionally MAX_THINKING_TOKENSenabled with a budget (tested)
A gateway that maps sonnet or haiku to an older Claude modelSet ANTHROPIC_MODEL to the real ID, such as claude-haiku-4-5, if your gateway accepts that nameenabled, budget 31999 by default (tested with claude-haiku-4-5 and claude-sonnet-4-5)
Opus, Sonnet or Haiku 5.5 behind an endpoint that rejects adaptiveCLAUDE_CODE_DISABLE_THINKING=1; the model decides how much to thinkNo thinking field

Three places to fix the adaptive request: in Claude Code, remove the field with CLAUDE_CODE_DISABLE_THINKING=1 or keep thinking with modelOverrides from a dated Claude 4.5 ID, rewrite it to enabled with budget_tokens in a gateway, or use a provider that accepts adaptive

Keep thinking on for GLM or DeepSeek with modelOverrides

modelOverrides maps an Anthropic model ID to the string Claude Code actually sends to your endpoint. The Claude Code model configuration docs on overriding model IDs say the mapping also applies to an ID passed through ANTHROPIC_MODEL. Claude Code then builds the request as if it were running the Claude model, including thinking, and only swaps the name:

json
{
  "modelOverrides": {
    "claude-sonnet-4-5-20250929": "Pro/zai-org/GLM-5"
  },
  "env": {
    "ANTHROPIC_BASE_URL": "https://your-endpoint.example.com",
    "ANTHROPIC_AUTH_TOKEN": "your-api-key",
    "ANTHROPIC_MODEL": "claude-sonnet-4-5-20250929"
  }
}

Merge both keys into your existing settings object, replace Pro/zai-org/GLM-5 with your provider's model ID, and leave CLAUDE_CODE_DISABLE_THINKING unset, since it would remove the field again. In the mock test this request went out as model: "Pro/zai-org/GLM-5" with {"type": "enabled", "budget_tokens": 31999}. MAX_THINKING_TOKENS=8000 lowered the budget to 8000, and mapping claude-haiku-4-5-20251001 to deepseek-v4-pro worked the same way.

Three things decide whether it works:

  • Use the dated ID as the key. The docs say dated model IDs need their date suffix and unknown keys are ignored. An entry keyed on claude-sonnet-4-5 wasn't applied, and the request went out under the name claude-sonnet-4-5.
  • Map from a Claude 4.5 ID, not a 5.5 one. Mapping claude-sonnet-5-5 to the GLM ID still sent adaptive and still failed. Claude Code builds the request for the model it selected, and 5.5 models always get adaptive.
  • Claude Code now treats the session as Claude Sonnet 4.5 (or Haiku 4.5). The "doesn't recognize the model" warning goes away, no output_config effort was sent, and Claude Code's own assumptions, such as the context window, follow that Claude model rather than your provider's.

This was tested only against the mock. Whether your provider honors budget_tokens is up to the provider. DeepSeek's Anthropic API compatibility page, for example, lists thinking as supported with budget_tokens ignored, and doesn't list which type values it accepts; DeepSeek's own endpoint wasn't called in the test. For DeepSeek or OpenRouter setup and first-run checks, see Claude Code with OpenRouter and DeepSeek: Setup, Routes, and First-Error Fixes.

Rewrite adaptive to enabled in a gateway or proxy

This route is reported by users, not tested here. In cc-switch discussion #5864, a user describes a request-body override of {"thinking": {"type": "enabled"}} that made SenseNova accept requests again. Check one thing before you copy any rewrite: SiliconFlow's docs make budget_tokens required when the type is enabled, so a rewrite without a budget may trade this 400 for another one. LiteLLM users should also note that, per issue #31030, drop_params wasn't applied on the /v1/messages pass-through route as of June 2026.

Other Claude Code thinking 400s that look similar

These errors also mention thinking, but they have different causes and different fixes:

MessageWhat it meansWhere to go
"thinking.type.enabled" is not supported for this model. Use "thinking.type.adaptive"…The opposite case: your Claude Code is too old for the model and sent enabled to a model that only takes adaptive. Run claude update.Claude Code error reference and AWS Bedrock Claude 400 Error: Match the Exact Message to the Fix
thinking blocks ... cannot be modifiedThinking or tool history in the conversation is out of order; /rewind usually clears it.AWS Bedrock Claude 400 Error: Match the Exact Message to the Fix
DeepSeek's message that content[].thinking must be passed backEarlier thinking content is missing from the conversation history sent back to DeepSeek. Not a thinking-type problem.DeepSeek's API docs
top_p or temperature deprecated on newer Opus modelsAnother field newer models reject.Claude Code Opus 4.7 top_p Deprecated? Fix the 400 Without Guesswork

Claude Code thinking type 400: FAQ

Does alwaysThinkingEnabled fix the Claude Code thinking type 400?

Partly. alwaysThinkingEnabled: false, which is what /config saves when you turn thinking off, cleared the error for a GLM model ID on Claude Code 2.1.306. For Claude 5.5 IDs, including the opus, sonnet and haiku aliases on that version, it is ignored, and the adaptive request still goes out. CLAUDE_CODE_DISABLE_THINKING=1 covered both cases.

Which Claude Code version started sending adaptive thinking?

Reports disagree, so there is no single version to point to. Alibaba Cloud Coding Plan users in cc-switch issue #1173 saw the change between v2.1.62 and v2.1.63 on February 28, 2026. A SiliconFlow user in issue #1489 reported 2.1.150 working and 2.1.153 failing. The model you pick changes the request too, so a model switch can trigger the error without an update.

Should I downgrade Claude Code to get rid of the thinking type 400?

Only as a last resort. An older client can't use newer Claude models: the Claude Code error reference lists minimum versions, such as v2.1.280 for Opus 5.5. You would also give up later fixes, and it's unclear which version to pin. CLAUDE_CODE_DISABLE_THINKING=1 fixes the same request on the current version.

Is the thinking type 400 a key or quota problem?

No. The endpoint read your request and rejected one value in it. Authentication and quota failures come back with different messages. If the curl check above succeeds with enabled and fails only with adaptive, your key and quota are working.

Why does Claude Code say it doesn't recognize my model?

It's a separate warning that shows up for gateway and vendor IDs. Claude Code assumes a 200K context window for any ID it doesn't know, which affects when it compacts. The model configuration docs section on gateway and custom model IDs explains how to set the real window. The warning is also a sign that CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING won't change your thinking request.

Sources11

External pages this guide links to, in the order they appear. Last updated Oct 21, 2026.

  1. 1.Anthropic-format Messages API referencedocs.siliconflow.cn/cn/docs/api/messages-post
  2. 2.Claude Code model configuration docscode.claude.com/docs/en/model-config
  3. 3.cc-switch issue #1489github.com/farion1231/cc-switch/issues/1489
  4. 4.jetbrains-cc-gui issue #801github.com/zhukunpenglinyutong/jetbrains-cc-gui/issues/801
  5. 5.cc-switch issue #1173github.com/farion1231/cc-switch/issues/1173
  6. 6.cc-switch discussion #5864github.com/farion1231/cc-switch/discussions/5864
  7. 7.LiteLLM issue #31030github.com/BerriAI/litellm/issues/31030
  8. 8.Claude Platform thinking troubleshooting pageplatform.claude.com/docs/en/build-with-claude/thinking-troubleshooting
  9. 9.Claude Code environment variable referencecode.claude.com/docs/en/env-vars
  10. 10.Anthropic API compatibility pageapi-docs.deepseek.com/guides/anthropic_api
  11. 11.Claude Code error referencecode.claude.com/docs/en/errors
More in Claude Code