You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bdf3cef
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/servers/handling-errors.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,11 @@ Now swap `ToolError` for `MCPError`.
60
60
* The **host** application gets the error instead, the same way it would if the tool didn't exist at all.
61
61
*`code`, `message`, and `data` arrive intact. `INVALID_PARAMS` is `-32602`; `mcp.types` exports it and the other JSON-RPC error codes (`INVALID_REQUEST`, `INTERNAL_ERROR`, ...) as constants so you never type a magic number.
62
62
63
+
A request for an unknown tool name also raises `MCPError` with code `-32602`. Direct
64
+
`MCPServer.call_tool()` calls raise `ToolNotFoundError`, a subclass of `ToolError`, for a
65
+
missing name. If an existing tool calls a missing tool, that failure remains an execution
66
+
error with `is_error=True`.
67
+
63
68
!!! check
64
69
Same lookup, same miss, but now the call *raises* on the client side instead of returning:
Copy file name to clipboardExpand all lines: docs/troubleshooting.md
+29-3Lines changed: 29 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -82,7 +82,7 @@ async def main() -> None:
82
82
83
83
`__aexit__` is the disconnection, which is why there is no `client.close()` to forget. **[Testing](get-started/testing.md)** is built on exactly this pattern.
`Unknown tool: get_forecast` is the same shape for a name the server never registered, and a bad argument is rejected the same way, against the tool's input schema, before your function ever runs.
97
+
A bad argument is rejected the same way, against the tool's input schema, before your function ever runs.
98
98
99
99
The fix is in your client: **check `result.is_error`**. A `try/except` around `call_tool` catches none of these, because there is nothing to catch. This is deliberate, and it is the single most useful thing on this page to internalise: the *model* chose the call, so the model gets the message and a chance to try again. **[Handling errors](servers/handling-errors.md)** is the whole story, including the `MCPError` path that *does* raise.
100
100
101
101
The bare form, `Error executing tool <name>` with no message, means the tool **crashed**: an exception it didn't anticipate escaped it (or its return value failed the output schema), and that exception's text is kept off the wire. The traceback is in the **server's log** at `ERROR`, as `Tool '<name>' raised an unexpected exception`.
The requested tool does not exist. The server returns a JSON-RPC error with code `-32602`,
126
+
and `Client.call_tool()` raises `MCPError`. Refresh the tool list and check the name you sent.
127
+
An existing tool that calls a missing tool still returns an execution error with `is_error=True`.
128
+
103
129
## `TypeError: The @tool decorator was used incorrectly. Did you forget to call it? Use @tool() instead of @tool`
104
130
105
131
You wrote `@mcp.tool` instead of `@mcp.tool()`. `tool()` is a decorator *factory*: without the parentheses, Python hands your function to its `name=` parameter.
*`ExceptionGroup: unhandled errors in a TaskGroup` is never the error. Read the **last line**; catching `MCPError`*inside* the `async with Client(...)` block skips the wrapping entirely.
429
-
*`call_tool` does not raise for a failing tool. `Error executing tool ...` and `Unknown tool: ...`are results: check `result.is_error`. No message after the tool name means it crashed, and the traceback is in the server log.
455
+
*`Error executing tool ...` is a result: check `result.is_error`. `Unknown tool: ...`for the requested name raises `MCPError` with code `-32602`. A bare execution-error message means the tool crashed; its traceback is in the server log.
430
456
*`Client must be used within an async context manager` -> use `async with`. `Use @tool() instead of @tool` -> add the parentheses.
431
457
*`has an invalid x-mcp-header annotation` -> only `str`, `int` and `bool` arguments can be marked.
432
458
*`Tool already exists:` in the server log is the only sign that two same-named tools collapsed into one.
0 commit comments