{"record":{"id":"b5a78b77f21641cf","repo":"microsoft/semantic-kernel","slug":"failed-to-call-tool-tool-name","errorCode":null,"errorMessage":"Failed to call tool '{tool_name}'.","messagePattern":"Failed to call tool '(.+?)'\\.","errorType":"exception","errorClass":"FunctionExecutionException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/mcp.py","lineNumber":622,"sourceCode":"\n    async def call_tool(\n        self, tool_name: str, **kwargs: Any\n    ) -> list[TextContent | ImageContent | BinaryContent | AudioContent | FunctionResultContent | FunctionCallContent]:\n        \"\"\"Call a tool with the given arguments.\"\"\"\n        if not self.session:\n            raise KernelPluginInvalidConfigurationError(\n                \"MCP server not connected, please call connect() before using this method.\"\n            )\n        if not self.load_tools_flag:\n            raise KernelPluginInvalidConfigurationError(\n                \"Tools are not loaded for this server, please set load_tools=True in the constructor.\"\n            )\n        try:\n            return _mcp_call_tool_result_to_kernel_contents(await self.session.call_tool(tool_name, arguments=kwargs))\n        except McpError:\n            raise\n        except Exception as ex:\n            raise FunctionExecutionException(f\"Failed to call tool '{tool_name}'.\") from ex\n\n    async def get_prompt(self, prompt_name: str, **kwargs: Any) -> list[ChatMessageContent]:\n        \"\"\"Call a prompt with the given arguments.\"\"\"\n        if not self.session:\n            raise KernelPluginInvalidConfigurationError(\n                \"MCP server not connected, please call connect() before using this method.\"\n            )\n        if not self.load_prompts_flag:\n            raise KernelPluginInvalidConfigurationError(\n                \"Prompts are not loaded for this server, please set load_prompts=True in the constructor.\"\n            )\n        try:\n            prompt_result = await self.session.get_prompt(prompt_name, arguments=kwargs)\n            return [_mcp_prompt_message_to_kernel_content(message) for message in prompt_result.messages]\n        except McpError:\n            raise\n        except Exception as ex:\n            raise FunctionExecutionException(f\"Failed to call prompt '{prompt_name}'.\") from ex","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/mcp.py#L604-L640","documentation":"Thrown by MCPPluginBase.call_tool (mcp.py:622) as a FunctionExecutionException, wrapping any non-McpError exception raised by self.session.call_tool. McpError instances are re-raised unchanged (they carry structured MCP error data); all other failures (transport, timeout, argument marshalling) are wrapped with the tool_name for context.","triggerScenarios":"The MCP server's call_tool raised a non-MCP exception, the network dropped, request_timeout elapsed, or arguments could not be serialized. Originates at mcp.py:619-623.","commonSituations":"Server-side tool threw a Python exception that surfaced generically; network interruption mid-call; timeout too short; argument schema mismatch causing serialization failure; server process crashed.","solutions":["Inspect the chained __cause__ (from ex) for the real error class and message.","Increase request_timeout if the tool is slow.","Verify the kwargs match the tool's declared input schema (names and JSON-serializable types).","Catch FunctionExecutionException separately from McpError: the former is transport/marshalling, the latter is a structured server error."],"exampleFix":"# before\ntry:\n    await plugin.call_tool(\"search\", q=123)  # wrong arg type\nexcept Exception:\n    ...\n\n# after\ntry:\n    await plugin.call_tool(\"search\", q=\"hello\")\nexcept FunctionExecutionException as ex:\n    log.error(\"tool failed: %s\", ex.__cause__)","handlingStrategy":"try-catch","validationCode":"# confirm args are JSON-serializable and match the tool schema before calling\nimport json\n\ndef args_match_schema(args: dict, schema: dict) -> bool:\n    required = set(schema.get(\"required\", []))\n    props = set(schema.get(\"properties\", {}).keys())\n    return required <= set(args) <= props and all(\n        json.dumps(v) is not None for v in args.values()\n    )","typeGuard":"import json\n\ndef args_are_json_serializable(args: dict) -> bool:\n    try:\n        json.dumps(args)\n        return True\n    except TypeError:\n        return False","tryCatchPattern":"from semantic_kernel.exceptions.function_exceptions import FunctionExecutionException\nfrom mcp.shared.exceptions import McpError\n\ntry:\n    await plugin.call_tool(\"search\", q=\"x\")\nexcept McpError:\n    raise  # structured server error, handle per MCP spec\nexcept FunctionExecutionException as ex:\n    log.error(\"call_tool failed: %r\", ex.__cause__)\n    # retry with a longer timeout or sanitized args","preventionTips":["Catch McpError and FunctionExecutionException separately; the former is structured, the latter is transport/marshalling.","Ensure kwargs are JSON-serializable and match the tool's input schema.","Size request_timeout to the slowest tool.","Inspect __cause__ for the real underlying exception."],"tags":["mcp","call-tool","timeout","error-wrapping","function-execution"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}