Claude Code sends the context_management field together with the anthropic-beta header that enables it, and this 400 means the field reached a backend that would not accept it: a gateway or proxy dropped the header, or forwarded the request to a backend with a different schema, such as Amazon Bedrock. Claude Code does not retry it. Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 (Claude Code 2.1.27 or later) to stop sending the field, or make the gateway forward anthropic-beta.
The error
// Through Kunavo: the upstream message as it reaches you,
// in the envelope Kunavo returns (type api_error, no request_id field):
{"type":"error","error":{"type":"api_error","message":"context_management: Extra inputs are not permitted (request id: …)"}}
// From Anthropic's API directly, as Claude Code prints it:
// API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"context_management: Extra inputs are not permitted"},"request_id":"req_011C..."}
// request_id varies per request; a gateway may drop it, or append its own id to the message.
// Same mismatch, other fields: tools.0.custom.eager_input_streaming, tools.N.custom.defer_loadingCauses and fixes at a glance
| Cause | Fix |
|---|---|
| A gateway forwards the body but drops anthropic-beta | Forward the header unchanged, or set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 on the client. |
| An Anthropic-format gateway in front of Amazon Bedrock or Google Cloud | Point Claude Code at that provider's own format (CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX), or set the flag. |
| Claude Code older than 2.1.27 | Update. Before 2.1.27 the flag did not cover context management. |
| The error names eager_input_streaming or defer_loading instead | Same mismatch, a beta tool field. The flag strips those from 2.1.77 on. |
Confirm the header is what's missing
Claude Code pairs each pre-release body field with the anthropic-beta value that enables it, and the two have to travel together: a gateway that strips the header while passing the body produces hard 400s, and only when both are missing does the feature switch off quietly (https://code.claude.com/docs/en/llm-gateway-protocol#feature-pass-through, as of September 2026). Send one request to your base URL with the field and its header, in the shape Anthropic's context-editing page uses, minus its web search tool (https://platform.claude.com/docs/en/build-with-claude/context-editing). The same 400 with the header present means the header is not reaching a backend that accepts it.
curl -s "$ANTHROPIC_BASE_URL/v1/messages" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: context-management-2025-06-27" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-4-6", "max_tokens": 64,
"messages": [{"role": "user", "content": "ping"}],
"context_management": {"edits": [{"type": "clear_tool_uses_20250919"}]}}'Stop Claude Code sending it: CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
This is the documented client-side fix: Claude Code's own error reference gives it for this message as the fallback when the gateway can't be made to forward the header (https://code.claude.com/docs/en/errors#extra-inputs-are-not-permitted). It strips Anthropic-specific anthropic-beta headers and beta tool-schema fields such as defer_loading and eager_input_streaming (https://code.claude.com/docs/en/env-vars), and the gateway guide adds that it stops the pre-release body fields too, context management included (https://code.claude.com/docs/en/llm-gateway-protocol#disable-pre-release-capabilities). It needs Claude Code 2.1.27 or later: that release, January 30, 2026, is the one whose changelog says the flag now avoids the context-management error for gateway users (https://code.claude.com/docs/en/changelog). The cost is pre-release capabilities and MCP tool search, so MCP tools load up front (from 2.1.227, managed settings can keep tool search on); adaptive reasoning is chosen by model, not by a beta, and stays on. Put it in the env block of ~/.claude/settings.json to apply it to every session (https://code.claude.com/docs/en/settings-reference#env).
claude --version # 2.1.27 or later
export CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
claude
# Every session, in ~/.claude/settings.json:
# { "env": { "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1" } }If you run the gateway: forward anthropic-beta, or bridge the format
Claude Code's gateway guide lists anthropic-version and anthropic-beta as headers to forward unchanged on an Anthropic-format route, and asks gateways to pass anthropic-* headers and body fields through as open lists rather than allowlisting the ones seen today, because each release adds new ones. It names a common source of this 400: a gateway that accepts Anthropic-format requests and forwards them to Amazon Bedrock. If that is your setup, expose the provider's own format and point Claude Code at it with the provider variables below; on that route Claude Code limits the beta headers and fields it sends to what the provider accepts (https://code.claude.com/docs/en/llm-gateway-connect#route-to-a-cloud-provider-through-a-gateway).
# Only if your gateway exposes the Amazon Bedrock format:
export ANTHROPIC_BEDROCK_BASE_URL=https://llm-gateway.example.com/bedrock
export CLAUDE_CODE_SKIP_BEDROCK_AUTH=1
export CLAUDE_CODE_USE_BEDROCK=1If you’re calling through Kunavo
Kunavo is one of the gateways this page is about. Its /v1/messages passes your JSON body upstream as sent, context_management included — the only changes are the model id and, on models that reject them, dropping temperature, top_p and top_k — but it does not forward anthropic-beta: the only headers it sets upstream are its own credential, the content type and anthropic-version: 2023-06-01. That is the forwarded-body, dropped-header combination Claude Code's error reference names. Claude Code requests through Kunavo have failed with this message; we have not tested whether the upstream channel serving Claude today still rejects the field, so assume it can — it is not a mistake in your setup. Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 when you use Claude Code with Kunavo; it gives up little here, because no anthropic-beta value reaches the upstream through Kunavo anyway. The rejection arrives as HTTP 400 typed api_error, carrying the upstream's message text (which can end with the upstream's own request id); neither Kunavo nor Claude Code retries it, and it is not billed. The rest of the Claude Code setup for Kunavo is in the Claude Code integration guide.
FAQ
What does “context_management: Extra inputs are not permitted” mean?
The API, or the backend behind your gateway, received a context_management field it does not accept. On Anthropic's API that field needs the context-editing beta header (context-management-2025-06-27), and Claude Code's error reference puts this message down to a proxy or gateway that stripped the anthropic-beta header. Claude Code sends the field and the header as a pair, so something in between dropped the header or forwarded the request to a backend with a different schema.
Does CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS turn off thinking or prompt caching?
No. Adaptive reasoning is selected by model, not by a beta, and standard prompt caching (cache_control) has no beta pairing. What the flag removes is pre-release capabilities — beta headers, beta tool fields, context management — plus MCP tool search, so MCP tools load up front. On older models that use manual extended thinking, interleaved thinking between tool calls needs a beta header, so that goes too.
Is there a switch that turns off context_management alone?
Not a documented one, as of September 2026. The flag covers every pre-release capability at once — the one carve-out, from Claude Code 2.1.227, is keeping MCP tool search on through managed settings — and a request for a context_management-only switch (anthropics/claude-code#64510) was closed as inactive. Don't build on variables that are not in Claude Code's environment-variable reference.
Should I downgrade Claude Code instead?
In January 2026 commenters on anthropics/claude-code#21612 reported 2.1.20 as the last version that worked, but the fix that shipped was 2.1.27, whose changelog entry makes the flag cover this error. A pin that old also misses 2.1.77, which made the flag strip beta tool fields. Set the flag and stay current.
The error names tools.0.custom.eager_input_streaming instead
Same kind of mismatch, different field: a tool-schema field reached a backend that rejects it. Behind a custom base URL, Claude Code sends that field — fine-grained tool streaming — only if you set CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING=1. The flag strips beta tool fields from 2.1.77, and 2.1.80 fixed fine-grained tool streaming 400s through proxies, Bedrock and Vertex.
Related guides
- Claude Code "API Error: bad_response_status_code" — reading the status underneath it
- Claude Code “API Error: 401 authentication_error” with a custom base URL — every cause
- LLM gateway — one API for every model: routing, fallback, billing & observability (2026)
- Claude API 400 “Invalid `signature` in `thinking` block” — what broke the signature, and how to recover
More error semantics live in the error reference; getting a key takes a minute via sign up and the authentication docs.