microsoft/semantic-kernel · error · JsonException

Expected array for ChatToolCall list

Error message

Expected array for ChatToolCall list

What it means

Thrown as a JsonException by ChatToolCallListJsonConverter.Read when the JSON token for a ChatToolCall list is neither null nor the start of a JSON array. The converter expects the 'tool_calls' field to be either null or an array of tool call objects; encountering an object, string, or number at that position is a schema violation.

Source

Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ChatToolCallListJsonConverter.cs:26

namespace Microsoft.SemanticKernel.Connectors.OpenAI;

/// <summary>
/// JSON converter for IReadOnlyList&lt;ChatToolCall&gt; that handles serialization and deserialization
/// of ChatToolCall objects using their basic properties.
/// </summary>
internal sealed class ChatToolCallListJsonConverter : JsonConverter<IReadOnlyList<ChatToolCall>>
{
    public override IReadOnlyList<ChatToolCall> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Null)
        {
            return [];
        }

        if (reader.TokenType != JsonTokenType.StartArray)
        {
            throw new JsonException("Expected array for ChatToolCall list");
        }

        var toolCalls = new List<ChatToolCall>();

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndArray)
            {
                break;
            }

            if (reader.TokenType == JsonTokenType.StartObject)
            {
                var toolCall = ReadChatToolCall(ref reader);
                if (toolCall != null)
                {
                    toolCalls.Add(toolCall);
                }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Verify the endpoint returns OpenAI-compatible JSON where tool_calls is always null or an array.
  2. If using a third-party OpenAI-compatible API, check their documentation for tool call response format compliance.
  3. Update the Semantic Kernel OpenAI connector to the latest version in case schema handling improved.
  4. Capture the raw response body to inspect the actual JSON structure of tool_calls.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    var result = await service.GetChatMessageContentAsync(history);
}
catch (JsonException ex) when (ex.Message.Contains("ChatToolCall"))
{
    logger.LogError(ex, "OpenAI-compatible endpoint returned malformed tool_calls array.");
    // fallback to non-tool-call retry or error the request
}

Prevention

When it happens

Trigger: The OpenAI-compatible API returns a response where 'tool_calls' is a JSON object or primitive instead of an array; a malformed or truncated response body; an API that is not fully OpenAI-compatible returning a different structure.

Common situations: Using a non-OpenAI endpoint that partially conforms to the OpenAI schema; response corruption due to streaming desync; proxy or gateway rewriting the response shape; a fine-tuned or custom inference server with non-standard tool call formatting.

Related errors


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