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
- Use a positive integer, or omit max_tokens to use the server default.
- Replace 0/-1 sentinels with None before sending.
- 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
- Never use 0/-1 as 'unlimited'; omit the field instead.
- Clamp computed budgets with max(1, ...).
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
- thinking parts require exactly one of 'thinking' or 'text'
- Invalid request body: {e}
- max_tokens must be positive
- 'role' must be one of {allowed} (case-insensitive).
- 'role' must be a string
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/4a1d0ebe96736aeb.
Report an issue: GitHub.