can1357/oh-my-pi · error
Tool ${toolCall.name} not found
Error message
Tool ${toolCall.name} not found What it means
During argument validation of an assistant tool call, the resolved `tool` variable is undefined — the model emitted a toolCall for a name that is not registered on the agent/session. The validate() helper throws this error synchronously; with lenientArgValidation tools it is caught and degraded to a parse-error result, but for normal tools it surfaces. It exists so unregistered tool names fail explicitly instead of crashing on `tool.parameters` lookups.
Source
Thrown at packages/agent/src/agent-loop.ts:2253
if (intentTracing) {
const { intent, strippedArgs } = extractIntent(toolCall.arguments);
argsForExecution = strippedArgs;
if (intent) {
toolCall.intent = intent;
} else if (typeof tool?.intent === "function") {
try {
const derived = tool.intent(strippedArgs as never)?.trim();
if (derived) {
toolCall.intent = derived;
}
} catch {
// intent function must never break tool execution
}
}
}
const validate = (args: Record<string, unknown>): Record<string, unknown> | undefined => {
try {
if (!tool) throw new Error(`Tool ${toolCall.name} not found`);
return validateToolArguments(tool, { ...toolCall, arguments: args });
} catch (validationError) {
if (tool?.lenientArgValidation) {
const fallback = { ...args };
delete fallback.__parseError;
delete fallback.__rawJson;
return fallback;
}
entry.args = "__parseError" in args ? { __parseError: args.__parseError } : args;
entry.validationErrorMessage =
validationError instanceof Error ? validationError.message : String(validationError);
return undefined;
}
};
const effectiveArgs = validate(argsForExecution);
if (effectiveArgs === undefined) continue;
entry.args = effectiveArgs;
if (!beforeToolCall || !tool) continue;View on GitHub (pinned to 9690622007)
Solutions
- Log/inspect the offending toolCall.name and ensure a tool with that exact name is registered on the session before prompting
- If tools are conditionally filtered, keep previously-offered tools registered until their pending calls complete (or return a proper tool-result error instead of dropping the tool)
- For a resumed session, restore the same toolset that produced the recorded tool calls
- Mark the tool lenientArgValidation only if you intend graceful degradation — it does not fix a missing tool registration
Example fix
// before
defineTool(agent, { name: "read-file", ... }); // registered with a dash
// model calls "read_file" -> Tool read_file not found
// after
const tool = defineTool({ name: "read_file", ... });
agent.addTool(tool); // name matches what the prompt/model uses Defensive patterns
Strategy: validation
Validate before calling
// Ensure every tool name the model can see is registered
for (const call of assistantMessage.content.filter(c => c.type === "toolCall")) {
if (!session.getTools().some(t => t.name === call.name)) {
console.warn(`model referenced unregistered tool: ${call.name}`);
}
} Type guard
function isToolNotFoundError(err: unknown, name?: string): err is Error {
return err instanceof Error && err.message.startsWith("Tool ") && err.message.endsWith("not found")
&& (name === undefined || err.message.includes(name));
} Try / catch
try {
const args = validateToolArguments(tool, toolCall);
} catch (err) {
if (isToolNotFoundError(err)) {
return createErrorToolResult(toolCall, `Unknown tool: ${toolCall.name}`); // let the model recover
}
throw err;
} Prevention
- Register tools before prompting and keep names consistent between prompts and registration
- When filtering tools by permissions/dialect, finish or cancel pending calls first
- On session resume, restore the same toolset that produced the recorded calls
- Normalize tool names (underscores vs dashes, case) if the provider mangles them
When it happens
Trigger: The message content contains a toolCall whose `name` does not match any tool in the session's tool registry, and validation of its arguments is attempted (e.g. during transcript repair / streaming argument validation where validate() runs on partially or fully parsed args).
Common situations: Model hallucinating a tool name not in the current toolset; tools removed or filtered (dialect/permission gating) between the call being emitted and executed; session resumed with a different tool configuration than when the call was recorded; typo in tool registration vs. prompt reference.
Related errors
- Soft tool requirement '${softRequiredTool}' was not satisfie
- Tool "${toolCall.name}" not found
- Validation failed for tool "${toolCall.name}": Tool call arg
- Validation failed for tool "${toolCall.name}":\n${errors}\n\
- replace_memory_files requires a files array
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1995934286315384.
Report an issue: GitHub.