can1357/oh-my-pi · error · AIError.ToolNotFoundError
Tool "${toolCall.name}" not found
Error message
Tool "${toolCall.name}" not found What it means
validateToolCall looks up the requested tool by name in the provided tools array and throws AIError.ToolNotFoundError when no tool matches. This happens after the model emitted a tool_call whose name is not registered in the current session/request, so its arguments can never be validated or executed.
Source
Thrown at packages/ai/src/utils/validation.ts:1902
for (const [key, entry] of recovered) {
if (!(key in out)) out[key] = entry;
}
return { value: out, changed: true };
}
const MAX_COERCION_PASSES = 5;
/**
* Finds a tool by name and validates the tool call arguments against its schema.
* @param tools Array of tool definitions
* @param toolCall The tool call from the LLM
* @returns The validated arguments
* @throws Error if tool is not found or validation fails
*/
export function validateToolCall(tools: Tool[], toolCall: ToolCall): ToolCall["arguments"] {
const tool = tools.find(t => t.name === toolCall.name);
if (!tool) {
throw new AIError.ToolNotFoundError(toolCall.name);
}
return validateToolArguments(tool, toolCall);
}
/** Cap per-field string lengths when embedding received args in an error message. */
const MAX_ERROR_ARG_STRING_LENGTH = 256;
function truncateArgsForError(value: unknown): unknown {
if (typeof value === "string") {
if (value.length <= MAX_ERROR_ARG_STRING_LENGTH) return value;
return `${value.slice(0, MAX_ERROR_ARG_STRING_LENGTH)}… [truncated ${value.length - MAX_ERROR_ARG_STRING_LENGTH} chars]`;
}
if (Array.isArray(value)) return value.map(truncateArgsForError);
if (value !== null && typeof value === "object") {
const out: Record<string, unknown> = {};
for (const [key, entry] of Object.entries(value)) out[key] = truncateArgsForError(entry);
return out;
}View on GitHub (pinned to 9690622007)
Solutions
- Ensure the exact same tools array used in the LLM request is passed to validateToolCall
- Log/inspect toolCall.name and compare against tool names for case or whitespace mismatches
- Handle ToolNotFoundError in the tool-call loop and return an error message back to the model so it can recover instead of crashing
- If a tool was renamed, map legacy names to new ones before validation
Example fix
// before
const args = validateToolCall(tools, toolCall); // throws if unknown
// after
let args;
try {
args = validateToolCall(tools, toolCall);
} catch (err) {
if (err instanceof AIError.ToolNotFoundError) {
return { toolCallId: toolCall.id, content: `Unknown tool: ${toolCall.name}` };
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
const known = new Set(tools.map(t => t.name));
if (!known.has(toolCall.name)) {
return { toolCallId: toolCall.id, content: `Unknown tool: ${toolCall.name}` };
} Type guard
function isKnownTool(tools: Tool[], toolCall: ToolCall): toolCall is ToolCall {
return tools.some(t => t.name === toolCall.name);
} Try / catch
try {
const args = validateToolCall(tools, toolCall);
} catch (err) {
if (err instanceof AIError.ToolNotFoundError) {
return { toolCallId: toolCall.id, isError: true, content: `Unknown tool ${toolCall.name}` };
}
throw err;
} Prevention
- Always pass the same tools array to the request and to validation
- Trim tool lists only together with conversation history the model saw
- Echo available tool names in the system prompt to reduce hallucination
- Map legacy/renamed tool names before validation
When it happens
Trigger: Calling validateToolCall(tools, toolCall) — or the higher-level runToolCall path — where toolCall.name does not exactly match any entry of tools: model hallucinated a tool name, the tool was removed/renamed between requests, or case/whitespace mismatch.
Common situations: Model hallucinating tool names not in the request; client-side tool registry trimmed for context but the model replayed an old tool call; renaming a tool server-side while resuming a stored conversation; multi-provider routing where the tool list sent differs from the one used for validation.
Related errors
- Validation failed for tool "${toolCall.name}": Tool call arg
- Validation failed for tool "${toolCall.name}":\n${errors}\n\
- Soft tool requirement '${softRequiredTool}' was not satisfie
- Tool ${toolCall.name} not found
- cachedContent cannot be combined with request-level ${incomp
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c80ae7798c73ad70.
Report an issue: GitHub.