alibaba/spring-ai-alibaba · error · IllegalStateException

Failed to get valid decision after

Error message

Failed to get valid decision after %d retries. Last invalid decision: %s

What it means

AgentScopeRoutingNode.getDecisionWithRetry throws this IllegalStateException after maxRetries attempts where each decision either failed or was invalid; lastInvalidDecision records the final rejected decision. Called from decision(), it is the retry-exhaustion path for obtaining a structured routing decision from the LLM.

Solutions

  1. Increase maxRetries for the routing node
  2. Inspect lastInvalidDecision in the message to fix the recurring schema/prompt problem
  3. Verify the model supports structured output matching RoutingDecisionSchema
  4. Add a fallback route in caller code instead of letting the exception propagate

Example fix

// before
AgentScopeRoutingNode node = AgentScopeRoutingNode.builder().maxRetries(1).build();
// after
AgentScopeRoutingNode node = AgentScopeRoutingNode.builder().maxRetries(3).build();
Defensive patterns

Strategy: retry

Validate before calling

if (maxRetries < 2) throw new ConfigException("routing needs retries >= 2 for flaky models");

Try / catch

try {
    decision = routingNode.decision(messages);
} catch (IllegalStateException e) {
    logger.error("Retries exhausted: {}", e.getMessage());
    return fallbackRouting(state);
}

Prevention

When it happens

Trigger: Every LLM call within getDecisionWithRetry either throws (parse errors, API errors) or returns a RoutingDecisionSchema that fails validation, until the retry budget is exhausted.

Common situations: Model output not conforming to the structured routing schema (malformed JSON); transient model API failures across all attempts; maxRetries set too low (e.g. 1) for a flaky model; prompt too ambiguous so decisions keep referencing unknown agents.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/1be64f9818734313. 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:195

						if (attempt > 0) {
							logger.info("AgentScopeRoutingAgent {} succeeded on retry attempt {}. Routed to: {}",
									rootAgent.name(), attempt, String.join(", ", decisionValues));
						}
						return decision;
					}
					lastInvalidDecision = decisionValues;
				} else {
					lastInvalidDecision = Collections.emptyList();
				}
			} catch (Exception e) {
				if (attempt == maxRetries) {
					logger.error("AgentScopeRoutingAgent {} failed on final attempt {}/{}", rootAgent.name(), attempt, maxRetries, e);
					throw e;
				}
				logger.warn("AgentScopeRoutingAgent {} attempt {}/{} encountered an error, will retry", rootAgent.name(), attempt, maxRetries, e);
			}
		}
		throw new IllegalStateException(
				String.format("Failed to get valid decision after %d retries. Last invalid decision: %s", maxRetries, lastInvalidDecision));
	}

	private static RoutingNode.RoutingDecision toRoutingDecision(RoutingDecisionSchema schema) {
		List<RoutingNode.AgentRouting> list = new ArrayList<>();
		for (RoutingDecisionSchema.AgentRoutingSchema e : schema.agents) {
			if (e != null && StringUtils.hasText(e.agent)) {
				list.add(new RoutingNode.AgentRouting(e.agent, e.query != null ? e.query : ""));
			}
		}
		return new RoutingNode.RoutingDecision(list);
	}
}

View on GitHub (pinned to f82da0b50f)