microsoft/semantic-kernel · error · FunctionExecutionException
Failed to call tool '{tool_name}'.
Error message
Failed to call tool '{tool_name}'. What it means
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.
Source
Thrown at python/semantic_kernel/connectors/mcp.py:622
async def call_tool(
self, tool_name: str, **kwargs: Any
) -> list[TextContent | ImageContent | BinaryContent | AudioContent | FunctionResultContent | FunctionCallContent]:
"""Call a tool with the given arguments."""
if not self.session:
raise KernelPluginInvalidConfigurationError(
"MCP server not connected, please call connect() before using this method."
)
if not self.load_tools_flag:
raise KernelPluginInvalidConfigurationError(
"Tools are not loaded for this server, please set load_tools=True in the constructor."
)
try:
return _mcp_call_tool_result_to_kernel_contents(await self.session.call_tool(tool_name, arguments=kwargs))
except McpError:
raise
except Exception as ex:
raise FunctionExecutionException(f"Failed to call tool '{tool_name}'.") from ex
async def get_prompt(self, prompt_name: str, **kwargs: Any) -> list[ChatMessageContent]:
"""Call a prompt with the given arguments."""
if not self.session:
raise KernelPluginInvalidConfigurationError(
"MCP server not connected, please call connect() before using this method."
)
if not self.load_prompts_flag:
raise KernelPluginInvalidConfigurationError(
"Prompts are not loaded for this server, please set load_prompts=True in the constructor."
)
try:
prompt_result = await self.session.get_prompt(prompt_name, arguments=kwargs)
return [_mcp_prompt_message_to_kernel_content(message) for message in prompt_result.messages]
except McpError:
raise
except Exception as ex:
raise FunctionExecutionException(f"Failed to call prompt '{prompt_name}'.") from exView on GitHub (pinned to c028a0c7dc)
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.
Example fix
# before
try:
await plugin.call_tool("search", q=123) # wrong arg type
except Exception:
...
# after
try:
await plugin.call_tool("search", q="hello")
except FunctionExecutionException as ex:
log.error("tool failed: %s", ex.__cause__) Defensive patterns
Strategy: try-catch
Validate before calling
# confirm args are JSON-serializable and match the tool schema before calling
import json
def args_match_schema(args: dict, schema: dict) -> bool:
required = set(schema.get("required", []))
props = set(schema.get("properties", {}).keys())
return required <= set(args) <= props and all(
json.dumps(v) is not None for v in args.values()
) Type guard
import json
def args_are_json_serializable(args: dict) -> bool:
try:
json.dumps(args)
return True
except TypeError:
return False Try / catch
from semantic_kernel.exceptions.function_exceptions import FunctionExecutionException
from mcp.shared.exceptions import McpError
try:
await plugin.call_tool("search", q="x")
except McpError:
raise # structured server error, handle per MCP spec
except FunctionExecutionException as ex:
log.error("call_tool failed: %r", ex.__cause__)
# retry with a longer timeout or sanitized args Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to call prompt '{prompt_name}'.
- Timeout waiting for OAuth callback
- Unsupported content type: {type(content)}
- Failed to enter context manager.
- MCP server not connected, please call connect() before using
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/b5a78b77f21641cf.
Report an issue: GitHub.