sgl-project/sglang · error · ValueError

max_tokens must be positive

Error message

max_tokens must be positive

What it means

Pydantic field validator on ChatCompletionRequest: max_tokens must be > 0 when provided. Zero or negative values are rejected at request parsing time.

Source

Thrown at python/sglang/srt/entrypoints/openai/protocol.py:414

    extra_key: Optional[Union[List[str], str]] = None
    # Cache salt for request caching
    cache_salt: Optional[Union[List[str], str]] = None
    # Priority for the request
    priority: Optional[int] = None

    # For custom metric labels
    custom_labels: Optional[Dict[str, str]] = None

    @model_validator(mode="before")
    @classmethod
    def _handle_deprecated_dp_rank(cls, values):
        return _migrate_deprecated_dp_rank(values)

    @field_validator("max_tokens")
    @classmethod
    def validate_max_tokens_positive(cls, v):
        if v is not None and v <= 0:
            raise ValueError("max_tokens must be positive")
        return v


class SpecTokensDetails(BaseModel):
    """Per-request speculative decoding statistics."""

    spec_accept_rate: float = 0.0
    spec_accept_length: float = 0.0
    spec_cap_length: float = 0.0
    spec_block_accept_length: float = 0.0
    spec_num_correct_drafts: int = 0
    spec_num_proposed_drafts: int = 0
    spec_verify_ct: int = 0
    spec_correct_drafts_histogram: List[int] = Field(default_factory=list)
    spec_cap_lens_histogram: List[int] = Field(default_factory=list)


class SglExt(BaseModel):

View on GitHub (pinned to 0132848349)

Solutions

  1. Use a positive integer, or omit max_tokens to use the server default.
  2. Replace 0/-1 sentinels with None before sending.
  3. Compute max_tokens defensively: max(1, min(budget, context_len)).

Example fix

# before
client.chat.completions.create(..., max_tokens=0)
# after
client.chat.completions.create(...)  # or max_tokens=1024
Defensive patterns

Strategy: validation

Validate before calling

if max_tokens is not None:
    assert isinstance(max_tokens,int) and max_tokens>0

Type guard

def valid_max_tokens(v): return v is None or (isinstance(v,int) and not isinstance(v,bool) and v>0)

Prevention

When it happens

Trigger: Sending a chat completion request with max_tokens=0 or a negative number (e.g. -1 used as a sentinel).

Common situations: Clients using 0/-1 to mean 'unlimited'; config defaults bleeding in; arithmetic that computes max_tokens - remaining and goes negative.

Related errors


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