vllm-project/vllm · error · Error
tool_choice function `{name}` was not found in the available
Error message
tool_choice function `{name}` was not found in the available tools What it means
Request validation error (`request.rs:517`): `tool_choice` pins a specific function `name`, but no tool with that name exists in the request's `tools` array. The offending name is carried in the error. Maps to a 4xx at the API boundary (`error.rs:97`).
Source
Thrown at rust/src/chat/src/error.rs:78
#[error("harmony output parsing failed")]
HarmonyOutputParsing {
#[source]
error: BoxedError,
},
#[error(
"this model's maximum context length is {max_model_len} tokens, \
but the prompt contains {prompt_len} input tokens"
)]
PromptTooLong { max_model_len: u32, prompt_len: u32 },
#[error("chat request stream `{request_id}` closed before terminal output")]
StreamClosedBeforeTerminalOutput { request_id: String },
#[error("tool call stream state is inconsistent: {message}")]
ToolCallStreamInvariant { message: String },
#[error("duplicate tool name `{name}`")]
DuplicateToolName { name: String },
#[error("tool_choice requires at least one available tool")]
ToolChoiceRequiresTools,
#[error("tool_choice function `{name}` was not found in the available tools")]
ToolChoiceFunctionNotFound { name: String },
#[error("failed to build structural tag: {message}")]
StructuralTag { message: String },
#[error(transparent)]
Text(#[from] vllm_text::Error),
#[error(transparent)]
Tokenizer(#[from] vllm_tokenizer::TokenizerError),
}
pub type Result<T> = std::result::Result<T, Error>;
impl Error {
/// Whether this error represents invalid user request parameters.
pub fn is_request_validation_error(&self) -> bool {
match self {
Self::PromptTooLong { .. }
| Self::DuplicateToolName { .. }
| Self::ToolChoiceRequiresToolsView on GitHub (pinned to c794754062)
Solutions
- Verify the exact spelling/case of the function name against the tools array you are sending.
- Assert client-side that the pinned name exists in the tools list before issuing the request.
- Regenerate the tool names from a single source of truth (shared constants/registry) instead of string literals.
Example fix
// before choice.function.name = "get_wether"; // typo // after choice.function.name = WEATHER_TOOL_NAME; // shared constant "get_weather"
Defensive patterns
Strategy: validation
Validate before calling
if let Some(ToolChoice::Function { name }) = &request.tool_choice {
if !request.tools.iter().any(|t| &t.function.name == name) {
return Err(format!("tool_choice function `{name}` not in tools"));
}
} Type guard
fn pinned_tool_exists(choice: Option<&ToolChoice>, tools: &[Tool]) -> bool {
match choice {
Some(ToolChoice::Function { name }) => tools.iter().any(|t| &t.function.name == name),
_ => true,
}
} Try / catch
match result {
Err(vllm_chat::Error::ToolChoiceFunctionNotFound { name }) => {
respond_bad_request(format!("unknown tool `{name}` in tool_choice"))
}
other => other?,
} Prevention
- Reference tool names through shared constants generated from the tool definitions.
- Add a client-side assert that a pinned function exists in the same request's tools array.
When it happens
Trigger: `{"tool_choice": {"type": "function", "function": {"name": "get_weather"}}, "tools": [ ...no get_weather... ]}`; usually a typo or a stale name after a tool was renamed/removed.
Common situations: Tool registry drift between client and server; renamed functions during refactors; case mismatches (`GetWeather` vs `get_weather`).
Related errors
- tool_choice requires at least one available tool
- this model's maximum context length is {max_model_len} token
- duplicate tool name `{name}`
- chat request stream `{request_id}` closed before terminal ou
- failed to build structural tag: {message}
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/6e3dffad4ba83213.
Report an issue: GitHub.