BerriAI/litellm · error · AnthropicError
Invalid reasoning_effort: {reasoning_effort!r}. Must be one
Error message
Invalid reasoning_effort: {reasoning_effort!r}. Must be one of: 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none' What it means
Raised during translation of reasoning_effort for Anthropic models with adaptive thinking (output_config). The requested reasoning_effort string is mapped through REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT; for adaptive-thinking models an unmapped effort value (not in minimal/low/medium/high/xhigh/max/none) is a hard 400 AnthropicError, not a silent drop.
Source
Thrown at litellm/llms/anthropic/experimental_pass_through/messages/transformation.py:296
try:
mapped_thinking: Final = AnthropicConfig._map_reasoning_effort(
reasoning_effort=reasoning_effort,
model=model,
custom_llm_provider=custom_llm_provider,
)
except _BadRequestError as e:
raise AnthropicError(message=str(e.message), status_code=400)
if mapped_thinking is None:
optional_params.pop("thinking", None)
optional_params.pop("output_config", None)
return
optional_params.setdefault("thinking", mapped_thinking)
if AnthropicModelInfo._is_adaptive_thinking_model(model, custom_llm_provider):
mapped_effort: Final = REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(reasoning_effort)
if mapped_effort is None:
raise AnthropicError(
message=(
f"Invalid reasoning_effort: {reasoning_effort!r}. "
f"Must be one of: 'minimal', 'low', 'medium', 'high', "
f"'xhigh', 'max', 'none'"
),
status_code=400,
)
gate_error: Final = AnthropicConfig._validate_effort_for_model(model, mapped_effort, custom_llm_provider)
if gate_error is not None:
raise AnthropicError(message=gate_error, status_code=400)
existing_output_config = optional_params.get("output_config")
if not isinstance(existing_output_config, dict):
existing_output_config = {}
existing_output_config.setdefault("effort", mapped_effort)
optional_params["output_config"] = existing_output_config
@staticmethod
def _translate_legacy_thinking_for_adaptive_model(View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use one of: 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none'.
- If a newer effort level seems legitimate, upgrade litellm so the mapping table includes it.
- Pass the plain string, not an enum instance, as reasoning_effort.
Example fix
# before response = litellm.completion(model="anthropic/adaptive-model", reasoning_effort="extreme", ...) # after response = litellm.completion(model="anthropic/adaptive-model", reasoning_effort="high", ...)
Defensive patterns
Strategy: type-guard
Validate before calling
VALID_REASONING_EFFORTS = {"minimal", "low", "medium", "high", "xhigh", "max", "none"}
def validate_reasoning_effort(effort: str) -> None:
if effort not in VALID_REASONING_EFFORTS:
raise ValueError(f"reasoning_effort must be one of {sorted(VALID_REASONING_EFFORTS)}") Type guard
def is_valid_reasoning_effort(effort: object) -> bool:
return isinstance(effort, str) and effort in {
"minimal", "low", "medium", "high", "xhigh", "max", "none"
} Try / catch
try:
resp = litellm.completion(model=model, reasoning_effort=effort, ...)
except Exception as e:
if "Invalid reasoning_effort" in str(e):
resp = litellm.completion(model=model, reasoning_effort="medium", ...)
else:
raise Prevention
- Expose only the seven valid effort levels in your UI/config schema.
- Normalize incoming effort strings (lowercase, strip) before passing through.
- Upgrade litellm when Anthropic ships new effort levels.
When it happens
Trigger: Calling an adaptive-thinking Anthropic model (e.g. one whose model info sets adaptive thinking) with reasoning_effort='extreme' or any string outside the seven allowed values. Non-adaptive models tolerate unknown efforts (thinking is popped), but adaptive models raise here.
Common situations: Reasoning-effort strings from other SDKs (OpenRouter 'effort' values, custom 'ultra'); version mismatch where an older litellm does not know a newly added effort level; passing the enum object instead of its string value (mapped lookup misses).
Related errors
- WebSearchInterception: missing follow-up messages
- Invalid first message. Should always start with 'role'='user
- Unable to parse anthropic tool result for message: {message}
- Unable to parse anthropic file message: {message}
- Either file_data or file_id must be present in the file mess
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/8b3655d55bf83ed1.
Report an issue: GitHub.