vercel/ai · error · NoSuchToolError

Model tried to call unavailable tool '${toolName}'. Availabl

Error message

Model tried to call unavailable tool '${toolName}'. Available tools: ${availableTools.join(', ')}.

What it means

NoSuchToolError with the list of available tools, thrown when the model called a tool name that does not exist in the provided `tools` map (and the call is not a provider-executed dynamic tool). Includes `availableTools` so you can compare names.

Source

Thrown at packages/ai/src/generate-text/parse-tool-call.ts:181

async function doParseToolCall<TOOLS extends ToolSet>({
  toolCall,
  tools,
}: {
  toolCall: LanguageModelV4ToolCall;
  tools: TOOLS;
}): Promise<TypedToolCall<TOOLS>> {
  const toolName = toolCall.toolName as keyof TOOLS & string;

  const tool = getOwn(tools, toolName);

  if (tool == null) {
    // provider-executed dynamic tools are not part of our list of tools:
    if (toolCall.providerExecuted && toolCall.dynamic) {
      return await parseProviderExecutedDynamicToolCall(toolCall);
    }

    throw new NoSuchToolError({
      toolName: toolCall.toolName,
      availableTools: Object.keys(tools),
    });
  }

  const schema = asSchema(tool.inputSchema);

  // when the tool call has no arguments, we try passing an empty object to the schema
  // (many LLMs generate empty strings for tool calls with no arguments)
  const parseResult =
    toolCall.input.trim() === ''
      ? await safeValidateTypes({ value: {}, schema })
      : await safeParseJSON({ text: toolCall.input, schema });

  if (parseResult.success === false) {
    throw new InvalidToolInputError({
      toolName,
      toolInput: toolCall.input,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Compare error.toolName with error.availableTools and fix the tools key spelling/casing to match what the model calls.
  2. Ensure the same `tools` object is passed to every generateText/streamText step/agent invocation.
  3. Update the system prompt to reference the exact tool names defined in tools.
  4. Catch NoSuchToolError and instruct the model about available tools in a follow-up request.

Example fix

// before
const tools = { getCurrentWeather: tool({ ... }) };
// model calls "get_current_weather" -> NoSuchToolError
// after
const tools = { get_current_weather: tool({ ... }) };
Defensive patterns

Strategy: validation

Validate before calling

const available = Object.keys(tools);
if (available.length === 0) throw new Error('tools map must not be empty');
// verify prompt-referenced tool names exist:
for (const name of referencedToolNames) {
  if (!available.includes(name)) throw new Error(`prompt references unknown tool: ${name}`);
}

Try / catch

try {
  await generateText({ model, prompt, tools });
} catch (e) {
  if (NoSuchToolError.isInstance(e)) {
    console.error(`model called "${e.toolName}", available: ${e.availableTools?.join(', ')}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Model emits toolName 'get_weather' but tools defines 'getWeather'; tools passed to a different call/site than the one being parsed; key rename after refactor; multi-step where later steps lack the tools option.

Common situations: Typos or casing mismatch between model output and tool keys; renames in provider prompt docs; passing tools conditionally; agent frameworks stripping tools between steps; model hallucinating a similar tool name.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/954819ebcf29b3ba. Report an issue: GitHub.