sgl-project/sglang · error · ValueError

Exactly one of 'prompt' or 'messages' must be provided.

Error message

Exactly one of 'prompt' or 'messages' must be provided.

What it means

TokenizeRequest.validate_tokenize_input requires exactly one of 'prompt' or 'messages' to be set: the XOR condition fails if both are provided or neither is. The tokenizer needs an unambiguous input source.

Source

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

    model: str = DEFAULT_MODEL_NAME
    prompt: Optional[Union[str, List[str]]] = None
    messages: Optional[List[ChatCompletionMessageParam]] = None
    tools: Optional[List[Tool]] = Field(default=None, examples=[None])
    tool_choice: Optional[Union[ToolChoice, Literal["auto", "required", "none"]]] = (
        Field(default=None, examples=["auto"])
    )
    reasoning_effort: ReasoningEffortType = None
    continue_final_message: bool = False
    chat_template_kwargs: Optional[Dict] = None
    add_special_tokens: bool = Field(
        default=True,
        description="whether to add model-specific special tokens (e.g. BOS/EOS) during encoding.",
    )

    @model_validator(mode="after")
    def validate_tokenize_input(self) -> TokenizeRequest:
        if (self.prompt is None) == (self.messages is None):
            raise ValueError("Exactly one of 'prompt' or 'messages' must be provided.")
        return self

    def to_chat_completion_request(self) -> ChatCompletionRequest:
        data = self.model_dump(
            exclude={"prompt", "add_special_tokens"},
            exclude_none=True,
        )
        extra = getattr(self, "__pydantic_extra__", None)
        if extra:
            data.update(extra)
        return ChatCompletionRequest.model_validate(data)


class TokenizeResponse(BaseModel):
    """Response schema for the /tokenize endpoint."""

    tokens: Union[List[int], List[List[int]]]
    count: Union[int, List[int]]

View on GitHub (pinned to 0132848349)

Solutions

  1. Send only prompt (string) for raw text tokenization, or only messages for chat tokenization
  2. Check your request builder for accidental default empty values of both fields

Example fix

// before
{"model": "m", "prompt": "hi", "messages": [{"role":"user","content":"hi"}]}
// after
{"model": "m", "prompt": "hi"}
Defensive patterns

Strategy: validation

Validate before calling

has_p = "prompt" in body and body["prompt"] is not None
has_m = "messages" in body and body["messages"] is not None
assert has_p != has_m, "send exactly one of prompt/messages"

Type guard

def tokenize_payload_ok(b): return (b.get('prompt') is None) != (b.get('messages') is None)

Prevention

When it happens

Trigger: POST /tokenize with both prompt and messages in the body, or with neither field.

Common situations: Client code that always sends messages and also includes a leftover prompt field; conditional building that omits both when a variable is empty.

Related errors


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