microsoft/autogen · error · Exception

No user message found.

Error message

No user message found.

What it means

Thrown by the save-progress middleware in the two-agent application-form sample. The middleware does msgs.Last() ?? throw new Exception("No user message found.") — it requires a non-empty conversation before the 'application' agent can build its save-progress prompt. Note a latent naming bug: despite the name lastUserMessage, the code takes the last message of any role, so it only throws when the entire message list is empty.

Source

Thrown at dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example12_TwoAgent_Fill_Application.cs:88

    {
        var gpt4o = LLMConfiguration.GetOpenAIGPT4o_mini();
        var instance = new TwoAgent_Fill_Application();
        var functionCallConnector = new FunctionCallMiddleware(
            functions: [instance.SaveProgressFunctionContract],
            functionMap: new Dictionary<string, Func<string, Task<string>>>
            {
                { instance.SaveProgressFunctionContract.Name, instance.SaveProgressWrapper },
            });

        var chatAgent = new OpenAIChatAgent(
            chatClient: gpt4o,
            name: "application",
            systemMessage: """You are a helpful application form assistant who saves progress while user fills application.""")
            .RegisterMessageConnector()
            .RegisterMiddleware(functionCallConnector)
            .RegisterMiddleware(async (msgs, option, agent, ct) =>
            {
                var lastUserMessage = msgs.Last() ?? throw new Exception("No user message found.");
                var prompt = $"""
                Save progress according to the most recent information provided by user.

                ```user
                {lastUserMessage.GetContent()}
                ```
                """;

                return await agent.GenerateReplyAsync([lastUserMessage], option, ct);

            });

        return chatAgent;
    }

    public static async Task<IAgent> CreateAssistantAgent()
    {
        var gpt4o = LLMConfiguration.GetOpenAIGPT4o_mini();

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Ensure at least one user message exists in the conversation before routing to the application agent (in the sample, the user agent speaks first).
  2. Guard explicitly and return a neutral reply instead of throwing when no history exists.
  3. If the intent is truly 'last user message', filter by role (x.From == "user" or Role.User) rather than taking msgs.Last() — the current code also accepts assistant messages.
  4. When unit-testing, seed the message list with a TextMessage from the user.

Example fix

// before
var lastUserMessage = msgs.Last() ?? throw new Exception("No user message found.");

// after (correct semantics + graceful handling)
var lastUserMessage = msgs.LastOrDefault(m => m.From == "user");
if (lastUserMessage is null)
{
    return new TextMessage(Role.Assistant, "No user information yet; please provide your details.", from: "application");
}
Defensive patterns

Strategy: validation

Validate before calling

var lastUserMessage = msgs.LastOrDefault(m => m.From == "user");
if (lastUserMessage is null)
{
    return new TextMessage(Role.Assistant, "No user information yet; please provide your details.", from: "application");
}

Type guard

static bool HasUserMessage(IEnumerable<IMessage> msgs) =>
    msgs.Any(m => m.From == "user");

Try / catch

try
{
    return await agent.GenerateReplyAsync(msgs, option, ct);
}
catch (Exception ex) when (ex.Message == "No user message found.")
{
    return new TextMessage(Role.Assistant, "Please share your application details first.", from: "application");
}

Prevention

When it happens

Trigger: The application agent's GenerateReplyAsync is invoked with an empty msgs collection — e.g. the workflow starts with the application agent instead of the user agent, or a test calls the agent with no prior turns.

Common situations: Reordering the two-agent conversation so the assistant speaks first; unit-testing the application agent with an empty message list; upstream middleware filtering out all messages before this middleware runs.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/1ea5a192a426c127. Report an issue: GitHub.