{"record":{"id":"e980554c912ce3e5","repo":"zeroclaw-labs/zeroclaw","slug":"mcp-tool-tool-name-error","errorCode":null,"errorMessage":"MCP tool `{tool_name}` error {}: {}","messagePattern":"MCP tool `(.+?)` error (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/mcp_client.rs","lineNumber":745,"sourceCode":"            let inner = self.inner.lock().await;\n            inner\n                .config\n                .tool_timeout_secs\n                .unwrap_or(DEFAULT_TOOL_TIMEOUT_SECS)\n                .min(MAX_TOOL_TIMEOUT_SECS)\n        };\n        let operation = format!(\"tool call `{tool_name}`\");\n        let resp = self\n            .dispatch_rpc(\n                \"tools/call\",\n                json!({ \"name\": tool_name, \"arguments\": arguments }),\n                tool_timeout,\n                &operation,\n            )\n            .await?;\n\n        if let Some(err) = resp.error {\n            bail!(\"MCP tool `{tool_name}` error {}: {}\", err.code, err.message);\n        }\n\n        let result = resp.result.unwrap_or(serde_json::Value::Null);\n\n        // MCP servers signal *tool-execution* failures (as opposed to JSON-RPC\n        // protocol errors) with HTTP 200 + `result.isError: true` and the detail\n        // in `result.content[].text`, per the MCP spec. Surface it (scrubbed and\n        // length-bounded) so the failure is visible to the model and the log.\n        let server_name = self.inner.lock().await.config.name.clone();\n        check_result_is_error(&result, tool_name, &server_name)?;\n\n        Ok(result)\n    }\n\n    /// Generic JSON-RPC method dispatch with the same timeout, bounded\n    /// reconnect, and error surfacing as `call_tool`. Returns the raw\n    /// `result` value; callers apply any method-specific envelope handling.\n    pub(crate) async fn dispatch_method(","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/mcp_client.rs#L727-L763","documentation":"call_tool received a JSON-RPC response whose top-level error object is set — a protocol-level failure (unknown tool, invalid params, server internal error), as opposed to isError:true, which signals tool-execution failure. The message embeds the JSON-RPC error code and the server's message text.","triggerScenarios":"Calling a tool name the server never advertised (-32601 method not found); arguments failing JSON-RPC param validation (-32602); server-internal errors returned as -32603; params that cannot be parsed against the expected shape.","commonSituations":"Tool renamed in a server upgrade while the caller still uses the old name; stale cached tool lists; argument type typos (string vs number) that the tool's inputSchema would have caught.","solutions":["Map the embedded code: -32601 unknown tool, -32602 invalid params, -32603 internal error — each points at a different fix","Re-fetch tools/list and call the exact advertised name","Validate arguments against the tool's inputSchema before the call","For -32603, inspect the server's own logs; the client surface just relays the server's message"],"exampleFix":"// before\nlet res = server.call_tool(\"fs_read\", json!({\"path\": p})).await?;\n\n// after: use the advertised name and schema\nlet tools = list_tools(&server).await?;\nlet t = tools.iter().find(|t| t.name.contains(\"read\")).context(\"no read tool\")?;\nvalidate_args(&t.input_schema, &args)?;\nlet res = server.call_tool(&t.name, args).await?;","handlingStrategy":"try-catch","validationCode":"// Resolve the tool name from the live registry, then validate args\nlet tools = list_tools(&server).await?;\nlet tool = tools.iter().find(|t| t.name == wanted).context(\"tool not advertised\")?;\nvalidate_against_schema(&args, &tool.input_schema)?;\nserver.call_tool(&tool.name, args).await?;","typeGuard":"fn is_jsonrpc_protocol_error(err: &anyhow::Error) -> bool {\n    let s = err.to_string();\n    s.contains(\"error -3\") // -32601 unknown tool, -32602 invalid params, -32603 internal\n}","tryCatchPattern":"Catch, extract the code from the message, and branch: -32601 -> refresh tool list and use the advertised name; -32602 -> fix arguments against the schema; -32603 -> inspect server logs, retry only if the server message indicates a transient fault.","preventionTips":["Never hardcode tool names; resolve them from tools/list at runtime","Re-validate cached tool schemas after server upgrades","Log the full code+message pair so -3260x triage is mechanical"],"tags":["mcp","json-rpc","tool-call","error-code"],"backgroundTag":"rpc-error-response","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}