vllm-project/vllm · error · TokenIdsError

allowed_token_ids should not be empty

Error message

allowed_token_ids should not be empty

What it means

`allowed_token_ids` (grammar-style token whitelist) was supplied as an empty list; the frontend rejects it in rust/src/text/src/lower/token_ids.rs:73 because an empty whitelist would make generation impossible (no token is ever allowed).

Source

Thrown at rust/src/text/src/lower/token_ids.rs:13

// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright contributors to the vLLM project

use std::result::Result;

use thiserror::Error;
use vllm_engine_core_client::protocol::sampling::EngineCoreSamplingParams;

use crate::SamplingLimits;

#[derive(Debug, Error)]
pub enum TokenIdsError {
    #[error("allowed_token_ids should not be empty")]
    EmptyAllowedTokenIds,
    #[error(
        "token_id(s) {token_ids:?} in {parameter} are out of vocabulary. \
         Vocabulary size: {vocab_size}"
    )]
    OutOfVocab {
        parameter: &'static str,
        token_ids: Vec<u32>,
        vocab_size: usize,
    },
}

fn validate_param(
    parameter: &'static str,
    token_ids: impl IntoIterator<Item = u32>,
    vocab_size: usize,
) -> Result<(), TokenIdsError> {
    let invalid_token_ids: Vec<_> = token_ids

View on GitHub (pinned to c794754062)

Solutions

  1. Omit allowed_token_ids (or send null) when you do not want a whitelist
  2. If building it dynamically, fall back to omitting the field when the filtered list is empty

Example fix

// before
req.allowed_token_ids = Some(matching_ids); // possibly empty

// after
req.allowed_token_ids = matching_ids.is_empty().then_none().or(Some(matching_ids));
// simpler: only set when non-empty
if !matching_ids.is_empty() { req.allowed_token_ids = Some(matching_ids); }
Defensive patterns

Strategy: validation

Validate before calling

if let Some(ids) = &request.allowed_token_ids {
    assert!(!ids.is_empty(), "allowed_token_ids must be non-empty when set");
}

Type guard

fn is_empty_allowed(e: &Error) -> bool {
    matches!(e, Error::TokenIds(TokenIdsError::EmptyAllowedTokenIds))
}

Try / catch

match err {
    Error::TokenIds(TokenIdsError::EmptyAllowedTokenIds) =>
        bad_request("omit allowed_token_ids instead of sending []"),
    _ => /* ... */
}

Prevention

When it happens

Trigger: Sending `allowed_token_ids: []` — typically a client that builds the list by filtering tokens and the filter matched nothing.

Common situations: Dynamic construction of a token whitelist from vocabulary lookups where all words are out-of-vocab; 'disable by emptying' patterns; default-initialized arrays sent unconditionally.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/fda54399e0de6821. Report an issue: GitHub.