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
- Let the auto-invocation pipeline produce tool messages rather than hand-building them.
- If constructing manually, ensure each Tool-role message contains exactly one FunctionResultContent with a non-null Result.
- 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
- Prefer the auto-invocation pipeline over manual tool-message construction.
- Validate that tool-role messages contain FunctionResultContent before sending.
- Avoid serialization round-trips that may drop content items.
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
- Invalid message content, only text, image url and document u
- A function name can contain only ASCII letters, digits, dash
- Auto-invocation with KernelFunctions is not supported when n
- Auto-invocation with AnyFunction is not supported when no ke
- The specified RequiredFunctions function {metadata.PluginNam
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/1d70d651ce3c093b.
Report an issue: GitHub.