{"record":{"id":"5048f294b7fd48d5","repo":"PrefectHQ/fastmcp","slug":"error-calling-tool-name-r-e","errorCode":null,"errorMessage":"Error calling tool {name!r}: {e}","messagePattern":"Error calling tool (.+?): (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/server.py","lineNumber":1555,"sourceCode":"                            \"not declare\",\n                            name,\n                        )\n                        raise\n                    logger.exception(f\"Error calling tool {name!r}\")\n                    # Handle actionable errors that should reach the LLM\n                    # even when masking is enabled\n                    if get_http_status_code(e) == 429:\n                        raise ToolError(\n                            \"Rate limited by upstream API, please retry later\"\n                        ) from e\n                    if is_timeout_error(e):\n                        raise ToolError(\n                            \"Upstream request timed out, please retry\"\n                        ) from e\n                    # Standard masking logic\n                    if self._mask_error_details:\n                        raise ToolError(f\"Error calling tool {name!r}\") from e\n                    raise ToolError(f\"Error calling tool {name!r}: {e}\") from e\n\n    async def read_resource(\n        self,\n        uri: str,\n        *,\n        version: VersionSpec | None = None,\n        run_middleware: bool = True,\n    ) -> ResourceResult:\n        \"\"\"Read a resource by URI.\n\n        This is the public API for reading resources. By default, middleware is applied.\n        Checks concrete resources first, then templates.\n\n        Args:\n            uri: The resource URI\n            version: Specific version to read. If None, reads highest version.\n            run_middleware: If True (default), apply the middleware chain.\n                Set to False when called from middleware to avoid re-applying.","sourceCodeStart":1537,"sourceCodeEnd":1573,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/server.py#L1537-L1573","documentation":"The unmasked variant of the tool-failure wrapper: with _mask_error_details=False, call_tool raises ToolError(f'Error calling tool {name!r}: {e}') including the original exception's message. This is the development/default mode where the client (and the LLM) can see why the tool failed.","triggerScenarios":"Any unhandled exception escaping tool._run while masking is disabled — bugs, bad arguments that slip past validation, upstream API errors other than 429/timeout — with the underlying message appended after the colon.","commonSituations":"Local development and testing; self-hosted servers that intentionally expose detailed errors; internal tools where callers are trusted developers.","solutions":["Read the '{e}' portion of the message — it names the actual failing cause and fix that directly","Handle the failing condition inside the tool and raise a deliberate ToolError with a clear message","Add argument validation in the tool signature so bad calls fail as ValidationError before the body runs","Enable masking in production if detailed messages should not reach clients"],"exampleFix":"// client-side: capture and inspect the detail\ntry:\n    result = await client.call_tool('my_tool', args)\nexcept ToolError as e:\n    print(e)  # Error calling tool 'my_tool': <root cause here>","handlingStrategy":"try-catch","validationCode":"sig = await client.get_tool('my_tool')  # or inspect list_tools() inputSchema\nassert set(expected_args) <= set(sig.inputSchema.get('properties', {})), 'arg mismatch'","typeGuard":"def is_tool_error_with_detail(e: BaseException) -> bool:\n    return isinstance(e, ToolError) and ': ' in str(e)","tryCatchPattern":"try:\n    result = await client.call_tool('my_tool', args)\nexcept ToolError as e:\n    root_cause = str(e).split(': ', 1)[-1]\n    logger.error('tool my_tool failed: %s', root_cause)\n    raise","preventionTips":["Read the message after ': ' — it names the actual cause","Match tool inputSchema exactly before calling","Enable masking in production; keep detail only where callers are trusted","Handle known upstream failure modes inside the tool with clear ToolError messages"],"tags":["tools","error-masking","debugging"],"backgroundTag":"tool-execution-failed","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}