{"record":{"id":"ad3e197b3e14d869","repo":"Hmbown/CodeWhale","slug":"mcp-error-in","errorCode":null,"errorMessage":"MCP error in '{}': {}","messagePattern":"MCP error in '(.+?)': (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":2109,"sourceCode":"                .await\n                .with_context(|| {\n                    format!(\n                        \"MCP method '{}' on server '{}' timed out after {}s\",\n                        method, self.name, timeout_secs\n                    )\n                }) {\n                Ok(Ok(response)) => response,\n                Ok(Err(error)) => return self.finish_guarded_error(error).await,\n                Err(error) => return self.finish_guarded_error(error).await,\n            };\n\n        if let Some(error) = response.get(\"error\") {\n            if self.config.reviewed_plugin.is_some() {\n                anyhow::bail!(\n                    \"Reviewed plugin MCP server returned an error in '{method}' (server details suppressed to protect environment-backed credentials)\"\n                );\n            }\n            return Err(anyhow::anyhow!(\n                \"MCP error in '{}': {}\",\n                method,\n                serde_json::to_string_pretty(error)?\n            ));\n        }\n\n        Ok(response\n            .get(\"result\")\n            .cloned()\n            .unwrap_or(serde_json::json!(null)))\n    }\n\n    /// Get discovered tools\n    pub fn tools(&self) -> &[McpTool] {\n        &self.tools\n    }\n\n    /// Get discovered resources","sourceCodeStart":2091,"sourceCodeEnd":2127,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/mcp.rs#L2091-L2127","documentation":"The non-reviewed path of call_method error handling: the MCP server answered tools/call, resources/read or prompts/get with a JSON-RPC `error` object and Codewhale forwards it pretty-printed, tagged with the method (crates/tui/src/mcp.rs:2109-2113). Unlike the reviewed-plugin variant, the full code/message object is visible to the caller.","triggerScenarios":"Invalid tool arguments (-32602), unknown tool name, server-side execution failures, or auth/limit errors returned as JSON-RPC errors on a per-call basis.","commonSituations":"Schema drift between discovered input schemas and actual server validation; transient upstream failures; tools that error on edge-case arguments.","solutions":["Read the code/message in the pretty-printed object - it is the server's diagnosis; correct the arguments or the server-side condition accordingly.","Validate arguments against the tool's input_schema (available from the discovered McpTool) before calling.","For transient upstream errors, retry the individual call after backoff."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match conn.call_tool(tool, args, timeout).await {\n    Ok(value) => value,\n    Err(err) => {\n        let msg = err.to_string();\n        if let Some(rest) = msg.strip_prefix(\"MCP error in \") {\n            // rest contains 'method': {pretty-printed JSON-RPC error}; parse\n            // code/message to decide between fix-args, retry, or fail.\n            tracing::warn!(error = %rest, \"MCP tool call error\");\n        }\n        return Err(err);\n    }\n}","preventionTips":["Validate arguments against the discovered input schema before each call.","Retry transient upstream failures (rate limits, 5xx) with backoff rather than failing the flow.","Keep the server's tool schemas in sync with what callers send."],"tags":["mcp","jsonrpc","protocol"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}