vllm-project/vllm · error · Error
duplicate tool name `{name}`
Error message
duplicate tool name `{name}` What it means
Request validation error raised at `request.rs:497` when the `tools` array contains two tool definitions with the same function name. Tool names are the dispatch key for `tool_choice` and for matching `tool_call_id`s, so duplicates are rejected up front. Classified as a user request error (`error.rs:95`).
Source
Thrown at rust/src/chat/src/error.rs:74
HarmonyParserOverrideUnsupported {
kind: &'static str,
selection: String,
},
#[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 {View on GitHub (pinned to c794754062)
Solutions
- Dedupe the tools array by function name before sending (keep last or error in client code).
- Namespace tool names per module (`fs_read_file` vs `db_read_file`) when merging registries.
- Add a unit test / lint that asserts uniqueness of tool names in your tool-registry builder.
Example fix
// before let tools = [fs_tools(), db_tools()]; // both contain "read" // after let tools = dedup_by_name([fs_tools(), db_tools()])?;
Defensive patterns
Strategy: validation
Validate before calling
let mut seen = HashSet::new();
for tool in &tools {
if !seen.insert(tool.function.name.as_str()) {
return Err(format!("duplicate tool name: {}", tool.function.name));
}
} Type guard
fn has_unique_tool_names(tools: &[Tool]) -> bool {
let mut seen = std::collections::HashSet::new();
tools.iter().all(|t| seen.insert(t.function.name.as_str()))
} Try / catch
match result {
Err(vllm_chat::Error::DuplicateToolName { name }) => {
respond_bad_request(format!("duplicate tool name `{name}`"))
}
other => other?,
} Prevention
- Dedupe-by-name in the tool registry builder, not at request time.
- Namespace tool names per plugin/module to avoid collisions by construction.
- Assert uniqueness in unit tests over the static tool list.
When it happens
Trigger: POSTing a chat completion with `tools: [{function:{name:"search"}}, {function:{name:"search"}}]`; common when programmatically merging tool lists from multiple modules without dedup.
Common situations: Combining tool registries from several plugins that each define `get_time` or `search`; renaming one tool but forgetting call sites that construct the list; copy-pasted tool JSON.
Related errors
- this model's maximum context length is {max_model_len} token
- tool_choice requires at least one available tool
- tool_choice function `{name}` was not found in the available
- 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/37aa38e1947814c6.
Report an issue: GitHub.