microsoft/semantic-kernel · error · InvalidOperationException

Failed to parse response: {responseText}

Error message

Failed to parse response: {responseText}

What it means

GetResponseAsync asks the chat completion service to return JSON (ResponseFormat set to the target type), then deserializes the response text into GroupChatManagerResult<TValue>. If JsonSerializer.Deserialize returns null — which happens when the LLM returns the literal JSON 'null' or an empty/partial response that deserializes to null — the ?? operator throws InvalidOperationException. Note: truly malformed JSON would throw JsonException before reaching this line.

Source

Thrown at dotnet/samples/GettingStartedWithAgents/Orchestration/Step03b_GroupChatWithAIManager.cs:211

        public override async ValueTask<GroupChatManagerResult<bool>> ShouldTerminate(ChatHistory history, CancellationToken cancellationToken = default)
        {
            GroupChatManagerResult<bool> result = await base.ShouldTerminate(history, cancellationToken);
            if (!result.Value)
            {
                result = await this.GetResponseAsync<bool>(history, Prompts.Termination(topic), cancellationToken);
            }
            return result;
        }

        private async ValueTask<GroupChatManagerResult<TValue>> GetResponseAsync<TValue>(ChatHistory history, string prompt, CancellationToken cancellationToken = default)
        {
            OpenAIPromptExecutionSettings executionSettings = new() { ResponseFormat = typeof(GroupChatManagerResult<TValue>) };
            ChatHistory request = [.. history, new ChatMessageContent(AuthorRole.System, prompt)];
            ChatMessageContent response = await chatCompletion.GetChatMessageContentAsync(request, executionSettings, kernel: null, cancellationToken);
            string responseText = response.ToString();
            return
                JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText) ??
                throw new InvalidOperationException($"Failed to parse response: {responseText}");
        }
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Log responseText before deserializing to inspect what the model actually returned.
  2. Use a model with strong JSON-mode / structured-output support and ensure ResponseFormat is correctly applied.
  3. Catch InvalidOperationException and retry with a clarifying system prompt or a different model.
  4. Use JsonSerializer.Deserialize into JsonElement first to verify the root is an object before binding to GroupChatManagerResult<TValue>.

Example fix

// before
return
    JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText) ??
    throw new InvalidOperationException($"Failed to parse response: {responseText}");

// after — validate structure before binding and retry on failure
using var doc = JsonDocument.Parse(responseText);
if (doc.RootElement.ValueKind != JsonValueKind.Object)
    throw new InvalidOperationException($"Expected a JSON object but got {doc.RootElement.ValueKind}. Raw: {responseText}");
return JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText)!
    ?? throw new InvalidOperationException($"Failed to parse response: {responseText}");
Defensive patterns

Strategy: try-catch

Validate before calling

// Inspect response text before deserializing
if (string.IsNullOrWhiteSpace(responseText) || responseText.Trim() == "null")
    throw new InvalidOperationException($"LLM returned null/empty response. Raw: '{responseText}'");

Type guard

bool IsValidManagerJson(string text) { try { using var doc = JsonDocument.Parse(text); return doc.RootElement.ValueKind == JsonValueKind.Object; } catch { return false; } }

Try / catch

try { return JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText) ?? throw new InvalidOperationException($"Null parse: {responseText}"); } catch (JsonException ex) { logger.LogWarning(ex, "Failed to parse manager response: {Text}", responseText); /* retry with clarifying prompt */ throw; }

Prevention

When it happens

Trigger: The LLM (acting as group chat manager) returns a response that is valid JSON but deserializes to null for GroupChatManagerResult<TValue> — e.g., the model outputs 'null', or returns a JSON value whose structure maps to null for the target type. This can happen when the model is confused by the prompt, when the ResponseFormat constraint isn't honored by the model, or when the model wraps the result in an unexpected structure.

Common situations: Using a model with weak structured-output / JSON-mode support; the system prompt for the manager is ambiguous; the model returns a different JSON shape (e.g., an array instead of an object) that doesn't bind to GroupChatManagerResult; token limits truncate the JSON; the model refuses the task and returns null-like content.

Understand the failure class

Related errors


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