microsoft/semantic-kernel · error · NotSupportedException

No function result provided in the tool message.

Error message

No function result provided in the tool message.

What it means

Thrown as a NotSupportedException when the tool-message conversion logic finishes without populating the messages list. It indicates a chat message with a Tool role was processed but no FunctionResultContent was found inside it to extract a result string. The connector cannot construct a valid Mistral tool-response message without a function result.

Source

Thrown at dotnet/src/Connectors/Connectors.MistralAI/Client/MistralClient.cs:773

            {
                if (item is not FunctionResultContent resultContent)
                {
                    continue;
                }

                messages ??= [];

                var stringResult = ProcessFunctionResult(resultContent.Result ?? string.Empty, toolCallBehavior);
                var name = $"{resultContent.PluginName}-{resultContent.FunctionName}";
                messages.Add(new MistralChatMessage(chatMessage.Role.ToString(), stringResult)
                {
                    Name = name,
                    ToolCallId = resultContent.CallId
                });
            }

            return messages
                ?? throw new NotSupportedException("No function result provided in the tool message.");
        }

        if (chatMessage.Items.Count == 1 && chatMessage.Items[0] is TextContent text)
        {
            return [new MistralChatMessage(chatMessage.Role.ToString(), text.Text)];
        }

        List<ContentChunk> content = [];
        foreach (var item in chatMessage.Items)
        {
            if (item is TextContent textContent && !string.IsNullOrEmpty(textContent.Text))
            {
                content.Add(new TextChunk(textContent.Text!));
                continue;
            }

            if (item is ImageContent imageContent)
            {

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Let the auto-invocation pipeline produce tool messages rather than hand-building them.
  2. If constructing manually, ensure each Tool-role message contains exactly one FunctionResultContent with a non-null Result.
  3. Inspect chatMessage.Items before sending; verify at least one FunctionResultContent exists for tool messages.

Example fix

// before
history.AddMessage(AuthorRole.Tool, "", metadata: null);

// after
history.Add(new ChatMessageContent(AuthorRole.Tool, "")
{
    Items = [new FunctionResultContent("myPlugin", "myFunc", callId, result)]
});
Defensive patterns

Strategy: validation

Validate before calling

foreach (var msg in chatHistory)
{
    if (msg.Role == AuthorRole.Tool &&
        !msg.Items.OfType<FunctionResultContent>().Any())
    {
        throw new InvalidOperationException("Tool message lacks a FunctionResultContent.");
    }
}

Type guard

static bool ToolMessagesHaveResults(ChatHistory history) =>
    history.All(m => m.Role != AuthorRole.Tool ||
        m.Items.OfType<FunctionResultContent>().Any());

Prevention

When it happens

Trigger: A chat message has AuthorRole.Tool but its Items collection contains no FunctionResultContent; or the FunctionResultContent is present but the code path that adds to 'messages' was bypassed (e.g., a malformed/hand-crafted ChatMessageContent).

Common situations: Manually constructing tool messages instead of using the auto-invocation pipeline; a serialization round-trip that dropped the FunctionResultContent; a plugin returned a null/empty result content item.

Related errors


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