{"record":{"id":"a5f9150eafd6d722","repo":"sgl-project/sglang","slug":"thinking-budget-tokens-is-not-allowed-when-thinkin-a5f915","errorCode":null,"errorMessage":"thinking.budget_tokens is not allowed when thinking.type is 'adaptive'","messagePattern":"thinking\\.budget_tokens is not allowed when thinking\\.type is 'adaptive'","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"python/sglang/srt/entrypoints/anthropic/protocol.py","lineNumber":308,"sourceCode":"            if self.budget_tokens < 1024:\n                raise ValueError(\n                    \"thinking.budget_tokens must be >= 1024 \"\n                    \"(got {})\".format(self.budget_tokens)\n                )\n        elif self.type == \"disabled\":\n            if self.budget_tokens is not None:\n                raise ValueError(\n                    \"thinking.budget_tokens is not allowed when \"\n                    \"thinking.type is 'disabled'\"\n                )\n            if self.display is not None:\n                raise ValueError(\n                    \"thinking.display is not allowed when \"\n                    \"thinking.type is 'disabled'\"\n                )\n        elif self.type == \"adaptive\":\n            if self.budget_tokens is not None:\n                raise ValueError(\n                    \"thinking.budget_tokens is not allowed when \"\n                    \"thinking.type is 'adaptive'\"\n                )\n        return self\n\n\nclass AnthropicTaskBudget(BaseModel):\n    \"\"\"Claude 4.7 ``output_config.task_budget`` — soft hint, not a hard cap.\n\n    Mirrors ``BetaTokenTaskBudgetParam`` in the Anthropic SDK: ``total``\n    and ``type`` are required; ``remaining`` is the client-tracked\n    countdown used for compaction. The hard cap on generation is still\n    ``max_tokens``; we never enforce ``task_budget`` ourselves.\n    \"\"\"\n\n    type: Literal[\"tokens\"]\n    total: int = Field(gt=0)\n    remaining: Optional[int] = Field(default=None, ge=0)","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/anthropic/protocol.py#L290-L326","documentation":"Raised by the Anthropic-compatible endpoint's validator when thinking.type='adaptive' (SGLang's adaptive thinking mode) and a budget_tokens value is also supplied. Adaptive thinking decides the budget itself, so an explicit budget_tokens is contradictory and rejected with a 400.","triggerScenarios":"POST /v1/messages with {\"thinking\": {\"type\": \"adaptive\", \"budget_tokens\": 2048}}.","commonSituations":"Switching a request template from 'enabled' to 'adaptive' without cleaning out budget_tokens; assuming adaptive accepts an upper bound like some providers' adaptive modes do.","solutions":["Remove budget_tokens when using thinking.type='adaptive'","Use thinking.type='enabled' with budget_tokens if you need an explicit cap"],"exampleFix":"// before\n{\"thinking\": {\"type\": \"adaptive\", \"budget_tokens\": 2048}}\n// after\n{\"thinking\": {\"type\": \"adaptive\"}}","handlingStrategy":"validation","validationCode":"if thinking[\"type\"] == \"adaptive\":\n    thinking = {\"type\": \"adaptive\"}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Adaptive mode takes no budget; don't reuse enabled-mode payloads"],"tags":["anthropic","thinking","adaptive","validation","request-validation"],"backgroundTag":"request-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}