{"record":{"id":"b24c8a752ad5866f","repo":"microsoft/semantic-kernel","slug":"expected-array-for-chattoolcall-list","errorCode":null,"errorMessage":"Expected array for ChatToolCall list","messagePattern":"Expected array for ChatToolCall list","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.OpenAI/Core/ChatToolCallListJsonConverter.cs","lineNumber":26,"sourceCode":"\nnamespace Microsoft.SemanticKernel.Connectors.OpenAI;\n\n/// <summary>\n/// JSON converter for IReadOnlyList&lt;ChatToolCall&gt; that handles serialization and deserialization\n/// of ChatToolCall objects using their basic properties.\n/// </summary>\ninternal sealed class ChatToolCallListJsonConverter : JsonConverter<IReadOnlyList<ChatToolCall>>\n{\n    public override IReadOnlyList<ChatToolCall> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType == JsonTokenType.Null)\n        {\n            return [];\n        }\n\n        if (reader.TokenType != JsonTokenType.StartArray)\n        {\n            throw new JsonException(\"Expected array for ChatToolCall list\");\n        }\n\n        var toolCalls = new List<ChatToolCall>();\n\n        while (reader.Read())\n        {\n            if (reader.TokenType == JsonTokenType.EndArray)\n            {\n                break;\n            }\n\n            if (reader.TokenType == JsonTokenType.StartObject)\n            {\n                var toolCall = ReadChatToolCall(ref reader);\n                if (toolCall != null)\n                {\n                    toolCalls.Add(toolCall);\n                }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.OpenAI/Core/ChatToolCallListJsonConverter.cs#L8-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the endpoint returns OpenAI-compatible JSON where tool_calls is always null or an array.","If using a third-party OpenAI-compatible API, check their documentation for tool call response format compliance.","Update the Semantic Kernel OpenAI connector to the latest version in case schema handling improved.","Capture the raw response body to inspect the actual JSON structure of tool_calls."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var result = await service.GetChatMessageContentAsync(history);\n}\ncatch (JsonException ex) when (ex.Message.Contains(\"ChatToolCall\"))\n{\n    logger.LogError(ex, \"OpenAI-compatible endpoint returned malformed tool_calls array.\");\n    // fallback to non-tool-call retry or error the request\n}","preventionTips":["Verify the endpoint is fully OpenAI-compatible for tool call responses.","Capture raw response bodies in staging to validate schema compliance.","Keep the Semantic Kernel OpenAI connector updated.","Test with a known OpenAI endpoint before switching to third-party providers."],"tags":["openai","json-deserialization","tool-calling","api-compatibility","json-exception"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}