{"record":{"id":"de2141d18edd6bbf","repo":"microsoft/semantic-kernel","slug":"failed-to-parse-response-responsetext","errorCode":null,"errorMessage":"Failed to parse response: {responseText}","messagePattern":"Failed to parse response: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/samples/GettingStartedWithAgents/Orchestration/Step03b_GroupChatWithAIManager.cs","lineNumber":211,"sourceCode":"        public override async ValueTask<GroupChatManagerResult<bool>> ShouldTerminate(ChatHistory history, CancellationToken cancellationToken = default)\n        {\n            GroupChatManagerResult<bool> result = await base.ShouldTerminate(history, cancellationToken);\n            if (!result.Value)\n            {\n                result = await this.GetResponseAsync<bool>(history, Prompts.Termination(topic), cancellationToken);\n            }\n            return result;\n        }\n\n        private async ValueTask<GroupChatManagerResult<TValue>> GetResponseAsync<TValue>(ChatHistory history, string prompt, CancellationToken cancellationToken = default)\n        {\n            OpenAIPromptExecutionSettings executionSettings = new() { ResponseFormat = typeof(GroupChatManagerResult<TValue>) };\n            ChatHistory request = [.. history, new ChatMessageContent(AuthorRole.System, prompt)];\n            ChatMessageContent response = await chatCompletion.GetChatMessageContentAsync(request, executionSettings, kernel: null, cancellationToken);\n            string responseText = response.ToString();\n            return\n                JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText) ??\n                throw new InvalidOperationException($\"Failed to parse response: {responseText}\");\n        }\n    }\n}\n","sourceCodeStart":193,"sourceCodeEnd":215,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/samples/GettingStartedWithAgents/Orchestration/Step03b_GroupChatWithAIManager.cs#L193-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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>."],"exampleFix":"// before\nreturn\n    JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText) ??\n    throw new InvalidOperationException($\"Failed to parse response: {responseText}\");\n\n// after — validate structure before binding and retry on failure\nusing var doc = JsonDocument.Parse(responseText);\nif (doc.RootElement.ValueKind != JsonValueKind.Object)\n    throw new InvalidOperationException($\"Expected a JSON object but got {doc.RootElement.ValueKind}. Raw: {responseText}\");\nreturn JsonSerializer.Deserialize<GroupChatManagerResult<TValue>>(responseText)!\n    ?? throw new InvalidOperationException($\"Failed to parse response: {responseText}\");","handlingStrategy":"try-catch","validationCode":"// Inspect response text before deserializing\nif (string.IsNullOrWhiteSpace(responseText) || responseText.Trim() == \"null\")\n    throw new InvalidOperationException($\"LLM returned null/empty response. Raw: '{responseText}'\");","typeGuard":"bool IsValidManagerJson(string text) { try { using var doc = JsonDocument.Parse(text); return doc.RootElement.ValueKind == JsonValueKind.Object; } catch { return false; } }","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["json","deserialization","orchestration","group-chat","llm-response","agents"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}