{"record":{"id":"8b3655d55bf83ed1","repo":"BerriAI/litellm","slug":"invalid-reasoning-effort-reasoning-effort-r-mu","errorCode":null,"errorMessage":"Invalid reasoning_effort: {reasoning_effort!r}. Must be one of: 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none'","messagePattern":"Invalid reasoning_effort: (.+?)\\. Must be one of: 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none'","errorType":"validation","errorClass":"AnthropicError","httpStatus":400,"severity":"error","filePath":"litellm/llms/anthropic/experimental_pass_through/messages/transformation.py","lineNumber":296,"sourceCode":"        try:\n            mapped_thinking: Final = AnthropicConfig._map_reasoning_effort(\n                reasoning_effort=reasoning_effort,\n                model=model,\n                custom_llm_provider=custom_llm_provider,\n            )\n        except _BadRequestError as e:\n            raise AnthropicError(message=str(e.message), status_code=400)\n\n        if mapped_thinking is None:\n            optional_params.pop(\"thinking\", None)\n            optional_params.pop(\"output_config\", None)\n            return\n\n        optional_params.setdefault(\"thinking\", mapped_thinking)\n        if AnthropicModelInfo._is_adaptive_thinking_model(model, custom_llm_provider):\n            mapped_effort: Final = REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(reasoning_effort)\n            if mapped_effort is None:\n                raise AnthropicError(\n                    message=(\n                        f\"Invalid reasoning_effort: {reasoning_effort!r}. \"\n                        f\"Must be one of: 'minimal', 'low', 'medium', 'high', \"\n                        f\"'xhigh', 'max', 'none'\"\n                    ),\n                    status_code=400,\n                )\n            gate_error: Final = AnthropicConfig._validate_effort_for_model(model, mapped_effort, custom_llm_provider)\n            if gate_error is not None:\n                raise AnthropicError(message=gate_error, status_code=400)\n            existing_output_config = optional_params.get(\"output_config\")\n            if not isinstance(existing_output_config, dict):\n                existing_output_config = {}\n            existing_output_config.setdefault(\"effort\", mapped_effort)\n            optional_params[\"output_config\"] = existing_output_config\n\n    @staticmethod\n    def _translate_legacy_thinking_for_adaptive_model(","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/anthropic/experimental_pass_through/messages/transformation.py#L278-L314","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"# before\nresponse = litellm.completion(model=\"anthropic/adaptive-model\", reasoning_effort=\"extreme\", ...)\n\n# after\nresponse = litellm.completion(model=\"anthropic/adaptive-model\", reasoning_effort=\"high\", ...)","handlingStrategy":"type-guard","validationCode":"VALID_REASONING_EFFORTS = {\"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\", \"none\"}\n\ndef validate_reasoning_effort(effort: str) -> None:\n    if effort not in VALID_REASONING_EFFORTS:\n        raise ValueError(f\"reasoning_effort must be one of {sorted(VALID_REASONING_EFFORTS)}\")","typeGuard":"def is_valid_reasoning_effort(effort: object) -> bool:\n    return isinstance(effort, str) and effort in {\n        \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\", \"none\"\n    }","tryCatchPattern":"try:\n    resp = litellm.completion(model=model, reasoning_effort=effort, ...)\nexcept Exception as e:\n    if \"Invalid reasoning_effort\" in str(e):\n        resp = litellm.completion(model=model, reasoning_effort=\"medium\", ...)\n    else:\n        raise","preventionTips":["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."],"tags":["anthropic","reasoning-effort","validation","adaptive-thinking"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}