40 min
Lesson 3 of 5
Error Handling & Validation
From the course AI Function Calling & Tool Use
Robust Function Call Handling
Production function calling requires careful error handling and input validation.
Input Validation
Never trust model-generated arguments blindly:
import { z } from "zod";
const SearchSchema = z.object({
query: z.string().min(1).max(200),
category: z.enum(["electronics", "clothing", "books"]),
maxPrice: z.number().positive().max(100000).optional(),
});
function handleToolCall(name: string, args: unknown) {
if (name === "search_products") {
const parsed = SearchSchema.safeParse(args);
if (!parsed.success) {
return { error: "Invalid arguments", details: parsed.error.issues };
}
return searchProducts(parsed.data);
}
}
Error Response Patterns
Return structured errors so the model can recover:
{
"error": true,
"code": "RATE_LIMITED",
"message": "API rate limit exceeded. Try again in 30 seconds.",
"retryable": true
}
Common Failure Modes
- Hallucinated functions — model invents function names that don't exist
- Wrong argument types — strings where numbers are expected
- Missing required fields — model omits required parameters
- Out-of-range values — valid type but nonsensical values
- Infinite loops — model keeps calling the same function
Safeguards
- Set a maximum number of tool call rounds per conversation
- Implement timeouts on function execution
- Log all function calls for debugging and auditing
- Use schema validation libraries (Zod, Ajv) for type safety
Common Pitfall: Returning Generic Error Messages to the Model
When a tool function fails, "Error occurred" gives the model no information to adapt. Return structured errors:
// Bad
return { error: "Failed" };
// Good
return {
error: true,
code: "NOT_FOUND",
message: "Product ID 'ABC123' was not found in the catalog.",
suggestion: "Try searching by product name instead of ID.",
retryable: false,
};
Best Practice: Implement a Tool Call Budget per Conversation
Set a maximum number of tool calls per conversation to prevent runaway API costs:
let toolCallCount = 0;
const MAX_TOOL_CALLS = 15;
async function executeTool(name: string, args: unknown) {
if (toolCallCount >= MAX_TOOL_CALLS) {
return { error: `Budget exceeded (${MAX_TOOL_CALLS} tool calls). Please summarize progress.` };
}
toolCallCount++;
return executeFunction(name, args);
}
Named Product Reference: LangChain Tool Agents
LangChain's createToolCallingAgent implements the agent loop with built-in parallel tool call support and error handling. Combined with LangSmith tracing, you get full visibility into every tool call decision — invaluable for debugging agents that take unexpected action sequences.
Key Takeaways
- •Always validate model-generated arguments with schema libraries
- •Return structured error objects so the model can recover gracefully
- •Guard against hallucinated functions and infinite call loops
- •Set round limits and timeouts for production safety
0 of 5 lessons marked complete
Progress is kept in this browser only.