jd-opensource/joyagent-jdgenie · error · Exception
调用工具 ' ' 失败
Error message
调用工具 '{name}' 失败: {str(e)} What it means
`call_tool` wraps any exception raised during the SSE session or the MCP tool invocation into an Exception prefixed with the tool name. The root cause (connection failure, tool-side error, invalid arguments returned by the server) is chained via `from e`.
Solutions
- Read the appended inner message / `__cause__` for the real cause
- Verify the tool exists via list_tools and its input schema matches your arguments dict
- Retry on transient network errors with backoff
- Reproduce the call manually (curl / direct MCP session) to isolate client vs server
Example fix
// before
await client.call_tool("search", args)
// after
try:
await client.call_tool("search", args)
except Exception as e:
logger.exception(e.__cause__) # unwrap the tool/server failure
raise Defensive patterns
Strategy: try-catch
Validate before calling
tools = {t.name for t in await client.list_tools()}
if name not in tools:
raise ValueError(f"Tool '{name}' not available on server") Type guard
async def tool_exists(client, name: str) -> bool:
tools = await client.list_tools()
return any(getattr(t, "name", None) == name for t in tools) Try / catch
try:
return await client.call_tool(name, args)
except Exception as e:
cause = e.__cause__
if isinstance(cause, (ConnectionError, TimeoutError)):
retry_with_backoff()
raise Prevention
- Discover tools with list_tools and validate names/arg schemas before calling
- Validate arguments against the tool's input schema
- Wrap calls in retry for transient network failures
When it happens
Trigger: `client.call_tool(name, arguments)` where the SSE connection fails, the server rejects the call, or the tool itself raises during execution.
Common situations: Calling a tool that doesn't exist on the server; tool argument schema mismatch; transient connectivity drop mid-call; server-side tool bug.
Related errors
AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08).
Data as JSON: /api/errors/f60543aaa0aa0bd5.
Report an issue: GitHub.
Appendix: source
Thrown at genie-client/app/client.py:335
elif not isinstance(arguments, dict):
raise ValueError("工具参数必须是字典类型")
try:
async with self._sse_connection() as session:
logger.info(f"正在调用工具 '{name}',参数: {arguments}")
# 调用工具
response = await session.call_tool(name=name, arguments=arguments)
logger.info(f"工具 '{name}' 执行成功")
logger.debug(f"工具 '{name}' 返回结果类型: {type(response).__name__}")
return response
except Exception as e:
error_msg = f"调用工具 '{name}' 失败: {str(e)}"
logger.error(error_msg)
raise Exception(error_msg) from e
def __str__(self) -> str:
"""返回客户端的字符串表示"""
return f"SseClient(server_url='{self.server_url}', timeout={self.timeout}s)"
def __repr__(self) -> str:
"""返回客户端的详细字符串表示"""
return (f"SseClient(server_url='{self.server_url}', "
f"timeout={self.timeout}, "
f"sse_read_timeout={self.sse_read_timeout}, "
f"headers_count={len(self.headers)})")
View on GitHub (pinned to 2417e0b8b6)