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
- Ensure at least one user message exists in the conversation before routing to the application agent (in the sample, the user agent speaks first).
- Guard explicitly and return a neutral reply instead of throwing when no history exists.
- 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.
- 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
- Filter by role/from before using a message instead of assuming msgs.Last() is a user message.
- Guarantee the user agent speaks first in two-agent workflows.
- Return instructional replies instead of throwing when history is empty.
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
- No user message found.
- No coder message found
- Failed to review code block
- Please set OPENAI_API_KEY environment variable.
- Please set OPENAI_API_KEY environment variable.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/1ea5a192a426c127.
Report an issue: GitHub.