alibaba/spring-ai-alibaba · error · IllegalStateException
AgentScopeRoutingAgent
Error message
AgentScopeRoutingAgent {rootAgent.name()} failed to get valid decision after retries. Invalid agents: {invalidAgents}. What it means
AgentScopeRoutingNode.apply throws this IllegalStateException when, after exhausting retries, the LLM's routing decision still references only invalid agent names (agents not among the routing root's sub-agents) so no valid MultiCommand can be produced. It names the root agent and the invalid agent names returned by the model.
Solutions
- Ensure every name the model can output exactly matches a registered sub-agent name (check the instruction lists correct agent names)
- Strengthen the routing instruction/schema to constrain the model to the exact agent name set
- Increase retries or switch to a stronger model for the routing decision
- Catch IllegalStateException around graph execution and fall back to a default route
Example fix
// before .subAgents(List.of(helperAgent)) // instruction mentions "assistant" // after .subAgents(List.of(assistantAgent)) // names align with instruction text
Defensive patterns
Strategy: try-catch
Validate before calling
// before execution: confirm instruction lists exact sub-agent names subAgents.forEach(a -> assert instruction.contains(a.name()));
Try / catch
try {
result = runnable.invoke(state);
} catch (IllegalStateException e) {
logger.warn("Routing failed: {}", e.getMessage());
state.put(defaultRouteKey, defaultAgentName);
} Prevention
- Keep sub-agent names stable and mirrored verbatim in the routing instruction
- Use a model with reliable structured-output support for routing
- Log rejected decisions to catch name drift early
When it happens
Trigger: The routing model repeatedly returns agent names in its decision that do not match any registered sub-agent name, so decisionValues remains empty after maxRetries and apply cannot build a MultiCommand.
Common situations: Sub-agent names renamed or refactored while the routing instruction prompt still mentions old names; the model hallucinates agent names not in the roster; case/whitespace mismatches between model output and registered agent keys; weak model that ignores the structured routing schema.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- AgentScope routing flow requires agentScopeModel in config…
- AgentScope routing flow requires at least one sub-agent
- AgentScope routing flow requires root agent to be…
- Failed to get valid decision after
- Routing sub-agents must be BaseAgent for merge support
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/9d64e01b75b39cc3.
Report an issue: GitHub.
Appendix: source
Thrown at spring-boot-starters/spring-ai-alibaba-starter-agentscope/src/main/java/com/alibaba/cloud/ai/agent/agentscope/flow/AgentScopeRoutingNode.java:118
List<String> decisionValues = decision.getAgentNames();
List<String> invalidAgents = decisionValues.stream()
.filter(agentName -> subAgents.stream().noneMatch(a -> a.name().equals(agentName)))
.collect(Collectors.toList());
if (invalidAgents.isEmpty() && !decisionValues.isEmpty()) {
if (decisionValues.size() == 1) {
logger.info("AgentScopeRoutingAgent {} routed to single sub-agent {}.", rootAgent.name(), decisionValues.get(0));
} else {
logger.info("AgentScopeRoutingAgent {} routed to {} sub-agents in parallel: {}.",
rootAgent.name(), decisionValues.size(), String.join(", ", decisionValues));
}
Map<String, Object> stateUpdate = new HashMap<>();
decision.getAgentQueries().forEach((agentName, query) ->
stateUpdate.put(agentName + "_input", query));
return new MultiCommand(decisionValues, stateUpdate);
}
throw new IllegalStateException(
"AgentScopeRoutingAgent " + rootAgent.name() + " failed to get valid decision after retries. Invalid agents: " + invalidAgents + ".");
}
private List<Message> prepareMessagesWithInstruction(List<Message> messages) {
List<Message> out = new ArrayList<>(messages);
String instruction = getInstruction();
if (StringUtils.hasLength(instruction)) {
out.add(new UserMessage(instruction));
} else {
out.add(new UserMessage(
"Based on the chat history and current task progress, please decide the next agent to delegate the task to."));
}
return out;
}
private String getInstruction() {
if (rootAgent instanceof AgentScopeRoutingAgent scopeAgent) {
return scopeAgent.getInstruction();View on GitHub (pinned to f82da0b50f)