--- title: "Tool Error Handling" description: "Learn how to handle errors when using tools with Arcade's Tool Development Kit (TDK)" --- import { Tabs } from "nextra/components"; import { ErrorHierarchy } from "@/app/_components/error-hierarchy"; # Tool error handling When calling tools from your Agent, smart error handling is crucial for creating robust and reliable applications. This guide covers everything you need to know about handling errors from a tool user's perspective. ## Error handling philosophy Arcade's error handling is designed to provide you with as much information as possible about the error that occurred. When an error occurs, Arcade's Engine will return a structured error object that you can use to understand the error and take appropriate action. ## Client error handling examples Here's how to handle different types of output errors when executing tools with Arcade's client libraries: ```python """ This example demonstrates how to handle different kinds of output errors when executing a tool. """ from arcadepy import Arcade # pip install arcadepy from arcadepy.types.execute_tool_response import OutputError # Requires arcadepy >= 1.8.0 def handle_tool_error(error: OutputError) -> None: """Example of how to identify different kinds of output errors.""" error_kind = error.kind if error_kind == OutputError.Kind.TOOL_RUNTIME_BAD_INPUT_VALUE: # You provided the executed tool with an invalid input value print(error.message) elif error_kind == OutputError.Kind.TOOL_RUNTIME_RETRY: # The tool returned a retryable error. Provide the additional # prompt content to the LLM and retry the tool call instructions_for_llm = error.additional_prompt_content print(instructions_for_llm) elif error_kind == OutputError.Kind.TOOL_RUNTIME_CONTEXT_REQUIRED: # The tool requires extra context from the user or orchestrator. # Provide the additional prompt content to them and then retry the # tool call with the new context request_for_context = error.additional_prompt_content print(request_for_context) elif error_kind == OutputError.Kind.TOOL_RUNTIME_FATAL: # The tool encountered a fatal error during execution print(error.message) elif error_kind == OutputError.Kind.UPSTREAM_RUNTIME_RATE_LIMIT: # The tool encountered a rate limit error from an upstream service # Wait for the specified amount of time and then retry the tool call seconds_to_wait = error.retry_after_ms / 1000 print(f"Wait for {seconds_to_wait} seconds before retrying the tool call") elif error_kind.startswith("UPSTREAM_"): # The tool encountered an error from an upstream service print(error.message) client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "{arcade_user_id}" tool_name = "Reddit.GetPostsInSubreddit" tool_input = {"subreddit": "programming", "limit": 1} # Go through the OAuth flow for the tool auth_response = client.tools.authorize( tool_name=tool_name, user_id=user_id, ) if auth_response.status != "completed": print(f"Click this link to authorize: {auth_response.url}") client.auth.wait_for_completion(auth_response) # Execute the tool response = client.tools.execute( tool_name=tool_name, input=tool_input, user_id=user_id, include_error_stacktrace=True, ) if response.output.error: handle_tool_error(response.output.error) ``` ```javascript /** * This example demonstrates how to handle different kinds of output errors when executing a tool. */ import { Arcade } from "@arcadeai/arcadejs"; // npm install @arcadeai/arcadejs // Requires @arcadeai/arcadejs >= 1.10.0 function handleToolError(error) { const errorKind = error.kind; if (errorKind === "TOOL_RUNTIME_BAD_INPUT_VALUE") { // You provided the executed tool with an invalid input value console.log(error.message); } else if (errorKind === "TOOL_RUNTIME_RETRY") { // The tool returned a retryable error. Provide the additional // prompt content to the LLM and retry the tool call const instructionsForLLM = error.additional_prompt_content; console.log(instructionsForLLM); } else if (errorKind === "TOOL_RUNTIME_CONTEXT_REQUIRED") { // The tool requires extra context from the user or orchestrator. // Provide the additional prompt content to them and then retry the // tool call with the new context const requestForContext = error.additional_prompt_content; console.log(requestForContext); } else if (errorKind === "TOOL_RUNTIME_FATAL") { // The tool encountered a fatal error during execution console.log(error.message); } else if (errorKind === "UPSTREAM_RUNTIME_RATE_LIMIT") { // The tool encountered a rate limit error from an upstream service // Wait for the specified amount of time and then retry the tool call const secondsToWait = error.retry_after_ms / 1000; console.log(`Wait for ${secondsToWait} seconds before retrying the tool call`); } else if (errorKind.startsWith("UPSTREAM_")) { // The tool encountered an error from an upstream service console.log(error.message); } } const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable const userId = "{arcade_user_id}"; const toolName = "Reddit.GetPostsInSubreddit"; const toolInput = { subreddit: "programming", limit: 1 }; // Go through the OAuth flow for the tool const authResponse = await client.tools.authorize({ tool_name: toolName, user_id: userId, }); if (authResponse.status !== "completed") { console.log(`Click this link to authorize: ${authResponse.url}`); } await client.auth.waitForCompletion(authResponse); // Execute the tool const response = await client.tools.execute({ tool_name: toolName, input: toolInput, user_id: userId, include_error_stacktrace: true, }); if (response.output.error) { handleToolError(response.output.error); } ``` ## Error types in Arcade client libraries To see the full structure of an OutputError, see [arcade-py OutputError](https://github.com/ArcadeAI/arcade-py/blob/942eb2cf41bc14b6c82f0e4acd8b11ef1978cb8d/src/arcadepy/types/execute_tool_response.py#L12) and [arcade-js OutputError](https://github.com/ArcadeAI/arcade-js/blob/902ef0ce9ff0412ca0d66a862cb4301759d3f87f/src/resources/tools/tools.ts#L166). ## Error types in MCP clients As of now, MCP Clients do not return structured error information, only an error message. Arcade will attempt to include the type of error in the error message, but it is not guaranteed. ## Best practices 1. **Let Arcade handle most errors**: There's no need to wrap your tool logic in try/catch blocks unless you need custom error handling. 2. **Use specific error types**: When you do need to raise errors explicitly, use the most specific error type available. 3. **Include additional context**: For `RetryableToolError` and `ContextRequiredToolError`, use the `additional_prompt_content` parameter to guide the LLM or user. ## Building tools with error handling To learn more about how to build tools with error handling, see the [Build Tools](/guides/create-tools/error-handling/useful-tool-errors) section.