{"record":{"id":"3bfb51f3208a89ec","repo":"microsoft/autogen","slug":"no-next-available-agents-found-in-the-current-work","errorCode":null,"errorMessage":"No next available agents found in the current workflow","messagePattern":"No next available agents found in the current workflow","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.Core/GroupChat/GroupChat.cs","lineNumber":120,"sourceCode":"    /// Select the next speaker based on the conversation history.\n    /// The next speaker will be decided by a combination effort of the admin and the workflow.\n    /// 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.\n    /// Otherwise, the admin will be invoked to decide the next speaker using role-play prompt.\n    /// </summary>\n    /// <param name=\"currentSpeaker\">current speaker</param>\n    /// <param name=\"conversationHistory\">conversation history</param>\n    /// <returns>next speaker.</returns>\n    [Obsolete(\"Please use RolePlayOrchestrator or WorkflowOrchestrator\")]\n    public async Task<IAgent> SelectNextSpeakerAsync(IAgent currentSpeaker, IEnumerable<IMessage> conversationHistory)\n    {\n        var agentNames = this.agents.Select(x => x.Name).ToList();\n        if (this.workflow != null)\n        {\n            var nextAvailableAgents = await this.workflow.TransitToNextAvailableAgentsAsync(currentSpeaker, conversationHistory);\n            agentNames = nextAvailableAgents.Select(x => x.Name).ToList();\n            if (agentNames.Count == 0)\n            {\n                throw new ArgumentException(\"No next available agents found in the current workflow\");\n            }\n\n            if (agentNames.Count == 1)\n            {\n                return this.agents.First(x => x.Name == agentNames.First());\n            }\n        }\n\n        if (this.admin == null)\n        {\n            throw new ArgumentException(\"No admin is provided.\");\n        }\n\n        var systemMessage = new TextMessage(Role.System,\n            content: $@\"You are in a role play game. Carefully read the conversation history and carry on the conversation.\nThe available roles are:\n{string.Join(\",\", agentNames)}\n","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.Core/GroupChat/GroupChat.cs#L102-L138","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nworkflow.AddTransition(Transition.Create(start, a));\nworkflow.AddTransition(Transition.Create(a, end)); // 'a' dead-ends after end\nvar next = await chat.SelectNextSpeakerAsync(end, history); // throws\n\n// after\nworkflow.AddTransition(Transition.Create(end, start)); // loop back so every node has an exit\nvar next = await chat.SelectNextSpeakerAsync(end, history);","handlingStrategy":"validation","validationCode":"// before asking for a next speaker, check the workflow has at least one transition from the current node\nvar hasExit = workflow.Transitions.Any(t => t.From == currentSpeakerNode);\nif (!hasExit) { /* end the chat or route manually */ }","typeGuard":null,"tryCatchPattern":"try { return await chat.SelectNextSpeakerAsync(currentSpeaker, history); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"No next available agents\"))\n{\n    return fallbackRoundRobin(currentSpeaker); // or terminate the conversation\n}","preventionTips":["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."],"tags":["autogen","dotnet","group-chat","workflow","orchestration","obsolete-api","argumentexception"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}