sgl-project/sglang · error · ValueError

max_tokens must be positive

Error message

max_tokens must be positive

What it means

Raised by the pydantic field validator on MessagesRequest when max_tokens is <= 0. The Anthropic API requires max_tokens (it is mandatory, not optional), and it must be a positive integer; otherwise the request is rejected with a 400 before inference.

Source

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

    top_k: Optional[int] = None
    top_p: Optional[float] = None
    # Claude 4.7 fields. The Anthropic SDK / Claude Code attach these even
    # when targeting non-Anthropic backends, so the schema must accept them.
    output_config: Optional[AnthropicOutputConfig] = None
    betas: Optional[list[str]] = None

    @field_validator("model")
    @classmethod
    def _validate_model(cls, v):
        if not v:
            raise ValueError("Model is required")
        return v

    @field_validator("max_tokens")
    @classmethod
    def _validate_max_tokens(cls, v):
        if v <= 0:
            raise ValueError("max_tokens must be positive")
        return v


# ---------- Stream deltas ----------
# Content-block deltas (discriminated by ``type``) vs message-end delta
# (separate model; the wire format does not put ``type`` inside its payload).


class TextDelta(BaseModel):
    type: Literal["text_delta"] = "text_delta"
    text: str


class InputJsonDelta(BaseModel):
    type: Literal["input_json_delta"] = "input_json_delta"
    partial_json: str

View on GitHub (pinned to 0132848349)

Solutions

  1. Set max_tokens to a positive integer (e.g. 1024+)
  2. If computing max_tokens dynamically, clamp it to a minimum of 1 (preferably more)
  3. Remember the Anthropic endpoint requires max_tokens; unlike OpenAI there is no unlimited default

Example fix

// before
{"model": "m", "max_tokens": 0, "messages": [...]}
// after
{"model": "m", "max_tokens": 1024, "messages": [...]}
Defensive patterns

Strategy: validation

Validate before calling

max_tokens = max(1, int(max_tokens)) if max_tokens else 1024

Type guard

def is_valid_max_tokens(v: object) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v > 0

Prevention

When it happens

Trigger: POST /v1/messages with max_tokens: 0, a negative value, or a computed value that evaluates to 0 (e.g. budget math or truncation arithmetic).

Common situations: Clients porting from OpenAI where max_tokens is optional and defaulting it to 0; dynamic computation like max_tokens = remaining_context - overflow that underflows to 0 or negative.

Related errors


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