You gave the agent twelve tools. It called thirteen.
The thirteenth was get_user_purchase_history_filtered. You don't have a tool with that name. You have get_purchase_history and filter_records. The agent decided those should be one function, invented the name, called it, received an error, and then — this is the part that hurts — processed the error as if it were real data.
Tool hallucination is real. It's not the same as making up a fact. It's making up a function. And unlike a hallucinated fact, which the user might catch, a hallucinated tool call happens silently inside the agent's execution.
Why this happens
The model knows what kinds of tools tend to exist. It's seen thousands of API schemas in training. When the task requires a capability that seems like it should exist — but doesn't exist in the tool list you provided — the model sometimes invents the nearest plausible function name and calls it.
The longer your tool list, the more this happens. Each additional tool trains the model's intuition that this is a "big API" with many capabilities. When it hits a gap, it fills it.
It also happens when your tool names are inconsistent. If you have list_users and fetch_orders and retrieve_products, the model has learned a mixed naming vocabulary. When it needs something and can't find the exact name, it constructs a name that fits the vocabulary pattern it's seen.
The failure chain
Step 1: Agent needs to retrieve filtered purchase history.
Step 2: Scans tool list. Finds get_purchase_history (returns all records) and filter_records (generic filter). Decides these should be one combined function for efficiency.
Step 3: Calls get_user_purchase_history_filtered with {"user_id": "u_123", "date_range": "last_30_days", "min_amount": 50}.
Step 4: Receives error: {"error": "function_not_found", "code": 404}.
Step 5: Interprets the error. The model sees 404 and a JSON object. It interprets this as "no records found" rather than "that function doesn't exist." Tells the user the purchase history is empty.
Step 6: User files a support ticket saying their order history is missing.
At no point did the agent stop and say "I don't have a tool for this." It improvised, failed, misread the failure, and reported a wrong result with confidence.
Why the error handling makes it worse
Most agents don't have explicit logic for "function not found." That error is treated the same as any other tool error: the model reads the response, interprets it in context, and continues.
A 404 response to a database query means "record not found." The model has seen that pattern many times. When it gets a 404 from a non-existent function, it applies the same interpretation.
If you're lucky, the agent says "I couldn't find any results." If you're unlucky, it fabricates results by combining what it knows from context with the partial error message.
The fixes
Schema validation before execution. Before any tool call executes, validate that the function name exists in the provided tool list. Reject calls to non-existent functions before they hit your infrastructure. Return a structured error that explicitly says "this tool does not exist in your schema" — not a generic 404.
Consistent naming conventions. Pick a naming pattern and enforce it. get_X, list_X, create_X, update_X, delete_X. Consistency reduces the model's tendency to invent plausible variants.
Minimum viable tool list. More tools means more hallucination. Give the agent the smallest set of tools that can accomplish the task. Additional tools are additional surface area for the model to get creative with.
Explicit error routing. Your error handler should distinguish between "tool returned an error" and "tool doesn't exist." These are different failures requiring different responses. The first might be retryable. The second should surface immediately as a design gap.
Faultmap checks tool call patterns before you deploy. It identifies which tool combinations the agent tends to conflate, which gaps in your tool schema the agent is likely to fill with invented functions, and whether your error handling distinguishes the two failure types.
The agent isn't confused about what tools exist. It's optimistic. It assumes the tool it needs probably exists and tries the most plausible name. That optimism costs you when the tool doesn't exist and the error handling is too permissive to catch the difference.

