{"record":{"id":"4a1d0ebe96736aeb","repo":"sgl-project/sglang","slug":"max-tokens-must-be-positive-4a1d0e","errorCode":null,"errorMessage":"max_tokens must be positive","messagePattern":"max_tokens must be positive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/entrypoints/openai/protocol.py","lineNumber":414,"sourceCode":"    extra_key: Optional[Union[List[str], str]] = None\n    # Cache salt for request caching\n    cache_salt: Optional[Union[List[str], str]] = None\n    # Priority for the request\n    priority: Optional[int] = None\n\n    # For custom metric labels\n    custom_labels: Optional[Dict[str, str]] = None\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def _handle_deprecated_dp_rank(cls, values):\n        return _migrate_deprecated_dp_rank(values)\n\n    @field_validator(\"max_tokens\")\n    @classmethod\n    def validate_max_tokens_positive(cls, v):\n        if v is not None and v <= 0:\n            raise ValueError(\"max_tokens must be positive\")\n        return v\n\n\nclass SpecTokensDetails(BaseModel):\n    \"\"\"Per-request speculative decoding statistics.\"\"\"\n\n    spec_accept_rate: float = 0.0\n    spec_accept_length: float = 0.0\n    spec_cap_length: float = 0.0\n    spec_block_accept_length: float = 0.0\n    spec_num_correct_drafts: int = 0\n    spec_num_proposed_drafts: int = 0\n    spec_verify_ct: int = 0\n    spec_correct_drafts_histogram: List[int] = Field(default_factory=list)\n    spec_cap_lens_histogram: List[int] = Field(default_factory=list)\n\n\nclass SglExt(BaseModel):","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/openai/protocol.py#L396-L432","documentation":"Pydantic field validator on ChatCompletionRequest: max_tokens must be > 0 when provided. Zero or negative values are rejected at request parsing time.","triggerScenarios":"Sending a chat completion request with max_tokens=0 or a negative number (e.g. -1 used as a sentinel).","commonSituations":"Clients using 0/-1 to mean 'unlimited'; config defaults bleeding in; arithmetic that computes max_tokens - remaining and goes negative.","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))."],"exampleFix":"# before\nclient.chat.completions.create(..., max_tokens=0)\n# after\nclient.chat.completions.create(...)  # or max_tokens=1024","handlingStrategy":"validation","validationCode":"if max_tokens is not None:\n    assert isinstance(max_tokens,int) and max_tokens>0","typeGuard":"def valid_max_tokens(v): return v is None or (isinstance(v,int) and not isinstance(v,bool) and v>0)","tryCatchPattern":null,"preventionTips":["Never use 0/-1 as 'unlimited'; omit the field instead.","Clamp computed budgets with max(1, ...)."],"tags":["openai-api","max-tokens","pydantic-validation"],"backgroundTag":"invalid-request-parameter","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}