microsoft/semantic-kernel · error · ValueError

No FunctionResultContent found in the message items

Error message

No FunctionResultContent found in the message items

What it means

Raised in _format_tool_message when formatting a TOOL-role ChatMessageContent whose first item is not a FunctionResultContent. The Azure AI Inference connector expects each tool message to carry exactly one tool result (it warns if there are more/fewer items, and hard-fails if the first item is not the expected result type), because it must extract .result and .id to build the API's tool message payload.

Solutions

  1. Ensure each TOOL message contains exactly one FunctionResultContent with .result (and ideally .id matching the tool_call_id).
  2. If you have multiple results, split into separate TOOL messages or ensure only FunctionResultContent items are present.
  3. Use SK's function-invocation middleware to produce tool messages rather than constructing them manually.

Example fix

# before
history.add_message(ChatMessageContent(
    role=AuthorRole.TOOL,
    items=[TextContent(text="42")],  # wrong item type → error
))

# after
from semantic_kernel.contents import FunctionResultContent
history.add_message(ChatMessageContent(
    role=AuthorRole.TOOL,
    items=[FunctionResultContent(id=call_id, name="calc", result="42")],
))
Defensive patterns

Strategy: validation

Validate before calling

from semantic_kernel.contents import FunctionResultContent

def tool_messages_have_result(history):
    for m in history:
        if m.role.name == "TOOL":
            assert m.items and isinstance(m.items[0], FunctionResultContent), \
                "Each TOOL message must start with a FunctionResultContent"

# call before sending history to the service

Type guard

from semantic_kernel.contents import FunctionResultContent

def is_valid_tool_message(message) -> bool:
    return (
        message.role.name == "TOOL"
        and len(message.items) == 1
        and isinstance(message.items[0], FunctionResultContent)
    )

Try / catch

try:
    await service.get_chat_message_contents(history=history, settings=settings)
except ValueError as e:
    if "FunctionResultContent" in str(e):
        # rebuild the offending tool message with a FunctionResultContent item
        ...

Prevention

When it happens

Trigger: A TOOL message whose items list is empty or whose first item is a different content type (e.g. a stray TextContent, FunctionCallContent, or ImageContent). Often a result of manually constructing a tool message without wrapping the result in FunctionResultContent.

Common situations: Building tool messages by hand instead of through the function-invocation pipeline; mixing content types into a tool message; bugs in middleware that replace items on tool messages.

Related errors


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

Appendix: source

Thrown at python/semantic_kernel/connectors/ai/azure_ai_inference/services/utils.py:144


def _format_tool_message(message: ChatMessageContent) -> ToolMessage:
    """Format a tool message to the expected object for the client.

    Args:
        message: The tool message.

    Returns:
        The formatted tool message.
    """
    if len(message.items) != 1:
        logger.warning(
            "Unsupported number of items in Tool message while formatting chat history for Azure AI"
            f" Inference: {len(message.items)}"
        )

    if not isinstance(message.items[0], FunctionResultContent):
        raise ValueError("No FunctionResultContent found in the message items")

    # The API expects the result to be a string, so we need to convert it to a string
    return ToolMessage(
        content=str(message.items[0].result), tool_call_id=message.items[0].id if message.items[0].id else "None"
    )


MESSAGE_CONVERTERS: dict[AuthorRole, Callable[[ChatMessageContent], ChatRequestMessage]] = {
    AuthorRole.SYSTEM: _format_system_message,
    AuthorRole.USER: _format_user_message,
    AuthorRole.ASSISTANT: _format_assistant_message,
    AuthorRole.TOOL: _format_tool_message,
    AuthorRole.DEVELOPER: _format_developer_message,
}

View on GitHub (pinned to c028a0c7dc)