microsoft/autogen · error · ArgumentException
No next available agents found in the current workflow
Error message
No next available agents found in the current workflow
What it means
In the obsolete SelectNextSpeakerAsync, when a workflow is set the chat calls TransitToNextAvailableAgentsAsync(currentSpeaker, history). If the workflow yields zero candidate agents for the current speaker, it throws ArgumentException('No next available agents found in the current workflow'). This means the current speaker has no outgoing transition that is currently enabled, so the conversation cannot continue along the workflow.
Source
Thrown at dotnet/src/AutoGen.Core/GroupChat/GroupChat.cs:120
/// Select the next speaker based on the conversation history.
/// The next speaker will be decided by a combination effort of the admin and the workflow.
/// Firstly, a group of candidates will be selected by the workflow. If there's only one candidate, then that candidate will be the next speaker.
/// Otherwise, the admin will be invoked to decide the next speaker using role-play prompt.
/// </summary>
/// <param name="currentSpeaker">current speaker</param>
/// <param name="conversationHistory">conversation history</param>
/// <returns>next speaker.</returns>
[Obsolete("Please use RolePlayOrchestrator or WorkflowOrchestrator")]
public async Task<IAgent> SelectNextSpeakerAsync(IAgent currentSpeaker, IEnumerable<IMessage> conversationHistory)
{
var agentNames = this.agents.Select(x => x.Name).ToList();
if (this.workflow != null)
{
var nextAvailableAgents = await this.workflow.TransitToNextAvailableAgentsAsync(currentSpeaker, conversationHistory);
agentNames = nextAvailableAgents.Select(x => x.Name).ToList();
if (agentNames.Count == 0)
{
throw new ArgumentException("No next available agents found in the current workflow");
}
if (agentNames.Count == 1)
{
return this.agents.First(x => x.Name == agentNames.First());
}
}
if (this.admin == null)
{
throw new ArgumentException("No admin is provided.");
}
var systemMessage = new TextMessage(Role.System,
content: $@"You are in a role play game. Carefully read the conversation history and carry on the conversation.
The available roles are:
{string.Join(",", agentNames)}
View on GitHub (pinned to 027ecf0a37)
Solutions
- Add an outgoing transition (e.g. back to the admin or to a termination-friendly node) from every node that may be asked for a next speaker.
- Loosen or fix the condition/predicate on the current speaker's transitions so at least one is satisfiable.
- Detect terminal state before calling selection: if the last speaker's node has no enabled transitions, end the chat instead of asking for a next speaker.
- Migrate to RolePlayOrchestrator/WorkflowOrchestrator, which this API is marked obsolete in favor of.
Example fix
// before workflow.AddTransition(Transition.Create(start, a)); workflow.AddTransition(Transition.Create(a, end)); // 'a' dead-ends after end var next = await chat.SelectNextSpeakerAsync(end, history); // throws // after workflow.AddTransition(Transition.Create(end, start)); // loop back so every node has an exit var next = await chat.SelectNextSpeakerAsync(end, history);
Defensive patterns
Strategy: validation
Validate before calling
// before asking for a next speaker, check the workflow has at least one transition from the current node
var hasExit = workflow.Transitions.Any(t => t.From == currentSpeakerNode);
if (!hasExit) { /* end the chat or route manually */ } Try / catch
try { return await chat.SelectNextSpeakerAsync(currentSpeaker, history); }
catch (ArgumentException ex) when (ex.Message.Contains("No next available agents"))
{
return fallbackRoundRobin(currentSpeaker); // or terminate the conversation
} Prevention
- Give every workflow node at least one outgoing transition.
- Test conditional transitions against representative histories so predicates are satisfiable.
- Prefer the non-obsolete RolePlayOrchestrator/WorkflowOrchestrator APIs which handle termination explicitly.
When it happens
Trigger: A workflow where the current speaker's transitions are all conditioned and their predicates return false for the current history; the speaker is a terminal node with no outgoing edges; calling the obsolete SelectNextSpeakerAsync API on such a node.
Common situations: Designing a graph with an end node and then asking for the next speaker anyway; conditional transitions (e.g. 'only route to reviewer if output contains X') whose conditions all fail; cycles that depend on a condition that never re-enables.
Related errors
- All agents in the workflow must be in the group chat.
- GroupChatManager does not have a name
- All agents must have a name.
- All agents must have a unique name.
- No admin is provided.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/3bfb51f3208a89ec.
Report an issue: GitHub.