{"record":{"id":"b61bfce6f92e5002","repo":"vllm-project/vllm","slug":"thinking-token-budget-must-be-a-non-negative-int","errorCode":null,"errorMessage":"`thinking_token_budget` must be a non-negative integer or -1 for unlimited.","messagePattern":"`thinking_token_budget` must be a non-negative integer or -1 for unlimited\\.","errorType":"validation","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"rust/src/text/src/error.rs","lineNumber":36,"sourceCode":"    #[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\nimpl Error {\n    /// Whether this error represents invalid user request parameters.\n    pub fn is_request_validation_error(&self) -> bool {\n        match self {\n            Self::PromptTooLong { .. }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/rust/src/text/src/error.rs#L18-L54","documentation":"Returned by `normalize_thinking_token_budget` (rust/src/text/src/lower.rs:204-210) when the request's `thinking_token_budget` is a negative number other than the `-1` sentinel. The contract mirrors Python vLLM's `validate_thinking_token_budget`: `None` and `-1` mean unlimited, values >= 0 pass through, any other negative value is rejected. It is a request-validation error surfaced to the API caller.","triggerScenarios":"Passing `thinking_token_budget: -2` (or any negative value besides -1) in a chat/completions request to the Rust frontend. Passing -1 is fine (unlimited); 0 and positives are fine.","commonSituations":"Clients using -1 from a different API's convention incorrectly (e.g. sending -2 or -100 to mean 'very large'); config templating that substitutes a negative default; serializing an Optional/int sentinel incorrectly from another language.","solutions":["Use a non-negative integer for thinking_token_budget, or -1 for unlimited","Pass null/None to leave the budget unset","Check client-side serialization: ensure a 'disabled' flag is not encoded as an arbitrary negative number"],"exampleFix":"// before\nrequest.thinking_token_budget = -2; // intending 'no budget'\n\n// after\nrequest.thinking_token_budget = -1; // unlimited sentinel\n// or\nrequest.thinking_token_budget = null; // unset","handlingStrategy":"validation","validationCode":"if let Some(budget) = request.thinking_token_budget {\n    assert!(budget == -1 || budget >= 0,\n        \"thinking_token_budget must be >= 0 or -1, got {budget}\");\n}","typeGuard":"fn is_invalid_thinking_budget(e: &Error) -> bool {\n    matches!(e, Error::InvalidThinkingTokenBudget)\n}","tryCatchPattern":"match lower_request(params) {\n    Err(Error::InvalidThinkingTokenBudget) => bad_request(\"thinking_token_budget must be >= 0 or -1\"),\n    other => other,\n}","preventionTips":["Encode 'unlimited' as exactly -1 (or null); never other negatives","Add a client-side unit test over the budget field's serialization"],"tags":["rust","validation","thinking","sampling-params","vllm"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}