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 ex

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect the chained __cause__ (from ex) for the real error class and message.
  2. Increase request_timeout if the tool is slow.
  3. Verify the kwargs match the tool's declared input schema (names and JSON-serializable types).
  4. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/b5a78b77f21641cf. Report an issue: GitHub.