{"record":{"id":"acab0f295953a1b7","repo":"microsoft/autogen","slug":"the-agent-did-not-produce-a-final-response-check","errorCode":null,"errorMessage":"The agent did not produce a final response. Check the agent's on_messages_stream method.","messagePattern":"The agent did not produce a final response\\. Check the agent's on_messages_stream method\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/AgentChat/GroupChat/ChatAgentRouter.cs","lineNumber":86,"sourceCode":"        // the lack of real type unions in C#, which is why we need to create the StreamingFrame type in the first\n        // place.\n        await foreach (ChatStreamFrame frame in this.agent.StreamAsync(this.MessageBuffer, messageContext.CancellationToken))\n        {\n            switch (frame.Type)\n            {\n                case ChatStreamFrame.FrameType.Response:\n                    await this.PublishMessageAsync(new GroupChatMessage { Message = frame.Response!.Message }, this.outputTopic);\n                    response = frame.Response;\n                    break;\n                case ChatStreamFrame.FrameType.InternalMessage:\n                    await this.PublishMessageAsync(new GroupChatMessage { Message = frame.InternalMessage! }, this.outputTopic);\n                    break;\n            }\n        }\n\n        if (response == null)\n        {\n            throw new InvalidOperationException(\"The agent did not produce a final response. Check the agent's on_messages_stream method.\");\n        }\n\n        this.MessageBuffer.Clear();\n\n        await this.PublishMessageAsync(new GroupChatAgentResponse { AgentResponse = response }, this.parentTopic);\n    }\n\n    public ValueTask HandleAsync(GroupChatReset item, MessageContext messageContext)\n    {\n        this.MessageBuffer.Clear();\n        return this.agent.ResetAsync(messageContext.CancellationToken);\n    }\n\n    async ValueTask<JsonElement> ISaveState.SaveStateAsync()\n    {\n        ChatAgentContainerState state = new ChatAgentContainerState\n        {\n            AgentState = new SerializedState(await this.agent.SaveStateAsync()),","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/AgentChat/GroupChat/ChatAgentRouter.cs#L68-L104","documentation":"ChatAgentRouter drains an agent's chat stream (StreamAsync) and requires at least one ChatStreamFrame of FrameType.Response; each Response frame sets the local 'response' variable. If the stream ends with only Text/Output/InternalMessage frames (response stays null), HandleAsync throws InvalidOperationException after forwarding the partial messages, so the parent never receives a GroupChatAgentResponse.","triggerScenarios":"Running a group chat where the selected agent's streaming implementation completes without a Response frame — e.g. an agent that streams only text chunks and returns, max-turn/early-exit logic that skips the final frame, or a custom IChatAgent adapter that forgets to yield the response frame.","commonSituations":"Plugging third-party or hand-rolled IChatAgent implementations into a team; agents whose HandleAsync stream finishes on a termination keyword before emitting the final response; middleware that filters the response frame out of the stream.","solutions":["Fix the agent so its HandleAsync stream always ends with a ChatStreamFrame(FrameType.Response, response) before completion","Check middleware around the agent for dropped frames, especially filters on frame type","If early termination is intentional, still synthesize and emit a final Response frame (e.g. from the last partial message) before ending the stream"],"exampleFix":"// before (IChatAgent.HandleAsync stream)\nawait foreach (var chunk in source) yield return ChunkFrame(chunk); // no Response frame\n// after\nawait foreach (var chunk in source) yield return ChunkFrame(chunk);\nyield return ResponseFrame(new ChatMessageResponse(finalMessage, innerMessages));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await team.RunAsync(task, ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"did not produce a final response\"))\n{\n    // inspect the agent's HandleAsync stream: it ended without a Response frame; fix the agent or its middleware\n}","preventionTips":["Every IChatAgent's HandleAsync stream must end with a Response frame, including on early termination","Test each agent standalone (stream it directly) before adding it to a team","Audit frame-filtering middleware so it never drops FrameType.Response"],"tags":["autogen","group-chat","streaming","router","contract","csharp"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}