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
- Log responseText before deserializing to inspect what the model actually returned.
- Use a model with strong JSON-mode / structured-output support and ensure ResponseFormat is correctly applied.
- Catch InvalidOperationException and retry with a clarifying system prompt or a different model.
- 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
- Use a model with strong JSON-mode / structured-output support.
- Log the raw LLM response text before deserializing.
- Add a retry loop that re-prompts the model if the response doesn't parse.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unknown participant selected: {response.content}.
- No messages in the chat history.
- Response is not available.
- {nameof(A2AAgent)} is not for use with {nameof(AgentChat)}.
- Missing agent description: {agent.Name ?? agent.Id}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/de2141d18edd6bbf.
Report an issue: GitHub.