{"record":{"id":"00556812e542aa30","repo":"vllm-project/vllm","slug":"min-tokens-must-be-less-than-or-equal-to-max-to","errorCode":null,"errorMessage":"`min_tokens` must be less than or equal to `max_tokens`, got min_tokens={min_tokens}, max_tokens={max_tokens}","messagePattern":"`min_tokens` must be less than or equal to `max_tokens`, got min_tokens=(.+?), max_tokens=(.+?)","errorType":"validation","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"rust/src/text/src/error.rs","lineNumber":31,"sourceCode":"pub enum Error {\n    #[error(\"tokenizer error: {0}\")]\n    Tokenizer(String),\n    #[error(\"text request `{request_id}` must contain at least one prompt token ID\")]\n    EmptyPromptTokenIds { request_id: String },\n    #[error(\"text request `{request_id}` stop strings cannot be empty\")]\n    EmptyStopString { request_id: String },\n    #[error(\n        \"this model's maximum context length is {max_model_len} tokens, \\\n         but the prompt contains {prompt_len} input tokens\"\n    )]\n    PromptTooLong { max_model_len: u32, prompt_len: u32 },\n    #[error(transparent)]\n    Logprobs(#[from] LogprobsError),\n    #[error(transparent)]\n    TokenIds(#[from] TokenIdsError),\n    #[error(transparent)]\n    SamplingParams(#[from] SamplingParamsError),\n    #[error(\n        \"`min_tokens` must be less than or equal to `max_tokens`, \\\n         got min_tokens={min_tokens}, max_tokens={max_tokens}\"\n    )]\n    MinTokensExceedsMaxTokens { min_tokens: u32, max_tokens: u32 },\n    #[error(\"`thinking_token_budget` must be a non-negative integer or -1 for unlimited.\")]\n    InvalidThinkingTokenBudget,\n    #[error(\"invalid repetition detection params: {message}\")]\n    InvalidRepetitionDetection { message: String },\n    #[error(\"text request stream `{request_id}` closed before terminal output\")]\n    StreamClosedBeforeTerminalOutput { request_id: String },\n    #[error(transparent)]\n    Llm(#[from] LlmError),\n    #[error(transparent)]\n    EngineCore(#[from] EngineCoreError),\n}\n\npub type Result<T> = std::result::Result<T, Error>;\n","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/rust/src/text/src/error.rs#L13-L49","documentation":"Thrown by the Rust text-frontend when lowering a completion/chat request: after `max_tokens` is resolved (request value, server default, or model-length-derived default via `resolve_max_tokens`) and `min_tokens` defaults to 0, the check `min_tokens > max_tokens` fails (rust/src/text/src/lower.rs:144). It is classified as a request-validation error (`is_request_validation_error` returns true), so the HTTP layer maps it to a 400-style client error, not a server fault.","triggerScenarios":"Calling the completions/chat API with `min_tokens` greater than the effective `max_tokens`. The effective max_tokens may be smaller than requested: it is capped by `max_model_len - prompt_len`, so a long prompt plus a modest `min_tokens` can trigger it even when the caller never set max_tokens explicitly.","commonSituations":"Clients porting from another engine that clamps instead of rejecting; setting `min_tokens` high to force long outputs while forgetting the server's default max_tokens; long prompts that shrink the derived max_tokens below min_tokens.","solutions":["Set min_tokens <= max_tokens (or omit min_tokens entirely; it defaults to 0)","If you need a longer guaranteed minimum output, raise max_tokens accordingly","Check that prompt_len + min_tokens does not exceed max_model_len; shorten the prompt or increase the model context if the derived max_tokens is the constraint"],"exampleFix":"// before\nparams.min_tokens = 500;\nparams.max_tokens = 200; // or unset, derived from remaining context\n\n// after\nparams.min_tokens = 200;\nparams.max_tokens = 500;","handlingStrategy":"validation","validationCode":"let effective_max = max_tokens.unwrap_or(max_model_len.saturating_sub(prompt_len));\nif let Some(min_tokens) = request.min_tokens {\n    assert!(min_tokens <= effective_max,\n        \"min_tokens {} exceeds effective max_tokens {}\", min_tokens, effective_max);\n}","typeGuard":"fn is_min_tokens_error(e: &Error) -> bool {\n    matches!(e, Error::MinTokensExceedsMaxTokens { .. })\n}","tryCatchPattern":"match lower_request(params) {\n    Err(Error::MinTokensExceedsMaxTokens { min_tokens, max_tokens }) => {\n        return bad_request(format!(\"min_tokens {min_tokens} > max_tokens {max_tokens}\"));\n    }\n    other => other,\n}","preventionTips":["Compute the effective max_tokens (request value or max_model_len - prompt_len) before choosing min_tokens","Treat min_tokens as optional and default to 0 instead of a large constant"],"tags":["rust","validation","sampling-params","vllm"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}