sgl-project/sglang · error · ValueError

thinking.budget_tokens is not allowed when thinking.type is

Error message

thinking.budget_tokens is not allowed when thinking.type is 'disabled'

What it means

Raised by the Anthropic-compatible endpoint's validator when a request sets thinking.type='disabled' but also supplies a budget_tokens value. Per the Anthropic contract, budget_tokens is only meaningful when thinking is enabled, so providing it alongside 'disabled' is rejected as a 400 before inference.

Source

Thrown at python/sglang/srt/entrypoints/anthropic/protocol.py:297

    display: Optional[Literal["summarized", "omitted"]] = None

    @model_validator(mode="after")
    def _validate_thinking_shape(self):
        # Cross-field rules mirror the SDK's three discriminated variants.
        if self.type == "enabled":
            if self.budget_tokens is None:
                raise ValueError(
                    "thinking.budget_tokens is required when "
                    "thinking.type is 'enabled'"
                )
            if self.budget_tokens < 1024:
                raise ValueError(
                    "thinking.budget_tokens must be >= 1024 "
                    "(got {})".format(self.budget_tokens)
                )
        elif self.type == "disabled":
            if self.budget_tokens is not None:
                raise ValueError(
                    "thinking.budget_tokens is not allowed when "
                    "thinking.type is 'disabled'"
                )
            if self.display is not None:
                raise ValueError(
                    "thinking.display is not allowed when "
                    "thinking.type is 'disabled'"
                )
        elif self.type == "adaptive":
            if self.budget_tokens is not None:
                raise ValueError(
                    "thinking.budget_tokens is not allowed when "
                    "thinking.type is 'adaptive'"
                )
        return self


class AnthropicTaskBudget(BaseModel):

View on GitHub (pinned to 0132848349)

Solutions

  1. Remove budget_tokens when thinking.type is 'disabled'
  2. Or switch thinking.type to 'enabled' if you actually want thinking
  3. Set budget_tokens to null/None instead of a number when disabling

Example fix

// before
{"thinking": {"type": "disabled", "budget_tokens": 2048}}
// after
{"thinking": {"type": "disabled"}}
Defensive patterns

Strategy: validation

Validate before calling

if thinking["type"] == "disabled":
    thinking.pop("budget_tokens", None)

Prevention

When it happens

Trigger: POST /v1/messages with {"thinking": {"type": "disabled", "budget_tokens": 1024}}. Any non-null budget_tokens together with type='disabled' triggers it.

Common situations: Toggling a previously-enabled thinking config to 'disabled' while leaving the budget field in place; building requests from a shared config object; SDK wrappers that always serialize budget_tokens even when unset becomes a number.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/6dad1ba6215be887. Report an issue: GitHub.