Skip to content
AI Engineering
Agents

When tools fail, and tool inputs are still inputs

Tool calls fail and tool arguments are written by a model. Handle both as you would handle any untrusted input.

Chapter 9: AgentsLesson 5 of 10Level: CoreAbout 12 min
Words on this page (7)
tool use
: The model asks your program to run a function and reads the result.
tool
: A function the model can ask your program to run, described by a name, description and argument schema.
schema
: A description of the shape of data: which fields exist and what types they have.
logarithm
: The power you raise a base to in order to get a number. log base 2 of 8 is 3 because 2 to the power 3 is 8.
agent
: A model run in a loop that chooses its own tools and steps until the task is done.
prompt
: The input text you give a model, including instructions, examples and data.
harness
: Everything around the model that makes it an agent: prompts, tools, rules, sandboxes, hooks, memory and checks.

Validate arguments

The model produces the arguments. They can be missing, the wrong type or dangerous. Validate against the before running anything. A "search" that builds a SQL string from the argument is an injection hole. Use parameterized queries, allowlists and limits. Treat the model like a user who may be tricked.

Return failures as results

If a tool fails, do not crash the loop. Return an error message as the tool result, written for the model: what failed and what to try. "No results for 'gift cards 2019'. Try a broader query or remove the year." The model can then retry with changes. Cap retries so a persistent failure ends the run with a clear message.

Keep the results honest

Return real data, not guesses, and say when a result is empty or truncated. Pass back any reasoning or tool-call items the provider requires in the next call, since dropping them can degrade behavior or cause an error. each call, its arguments and the result for later review.

Check the data path

Before wiring a tool into an , call it by hand with typical and bad inputs and read what it returns. A tool that works alone but returns a 40,000-token blob will wreck the agent's context.

A worked example: validating

Tool delete_file(path). The model passes "../../etc/passwd". Validation checks that the path stays inside the project folder and refuses with "Path must be inside the project." The model learns the rule and retries with a valid path. The check lives in code, not in the .

Limits on retries

Three attempts is a typical cap. After that, stop and report what was tried. An agent that retries forever burns money.

Three kinds of failure, three messages

Not every problem should be handled the same way.

A bad argument is the model's fault. Return "order_id must be digits only, got '#8123'". The model fixes it and retries.

A broken tool is the world's fault, such as a timeout. Return "The order service timed out. Retrying once may work." The can retry once itself.

An empty result is not a failure at all. Return "No order with id 8123 exists." Retrying will not help. The model should tell the user, not try again.

If all three return the same vague "Error", the model guesses, and often retries the one case that cannot work.

What goes wrong: the silent empty result

A tool catches every exception and returns an empty string. The model reads "nothing came back" as "no order exists" and tells the user their order is missing. The symptom is a confident wrong answer, while the logs show the tool returning empty at the same moment the database was down. Confirm it by switching off the service the tool depends on and reading what the tool returns. It should say it failed.

Check the value, not just the type

A schema can say quantity is an integer, and 1,000,000 is an integer. Types are only the first filter. Add checks on meaning: a refund must not exceed the order total, a date must not be in the past, a path must stay in the project folder. Put these checks in code beside the tool, where the model cannot talk its way around them.

Common mistake

Trusting that arguments will be shaped as described. Models make typos and can be manipulated.

Check yourself

A tool call fails. What should the loop do?

Why validate tool arguments?

A search tool builds a SQL string from the model's argument. What is the safe change?

Go deeper

Spotted a mistake or something unclear? Report it on GitHub.

On this page