{"record":{"id":"cff8c9f3ba7c6934","repo":"alibaba/spring-ai-alibaba","slug":"routingagent-attempt-returned-invalid-age","errorCode":null,"errorMessage":"RoutingAgent {} attempt {}/{} returned invalid agent name: {}","messagePattern":"RoutingAgent (.+?) attempt (.+?)/(.+?) returned invalid agent name: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/node/RoutingEdgeAction.java","lineNumber":221,"sourceCode":"\t\t\t\t}\n\n\t\t\t\tString decisionValue = decision.agent();\n\n\t\t\t\t// Check if it's a valid sub-agent name\n\t\t\t\tboolean isValidAgent = subAgents.stream()\n\t\t\t\t\t\t.anyMatch(agent -> agent.name().equals(decisionValue));\n\n\t\t\t\tif (isValidAgent) {\n\t\t\t\t\tif (attempt > 0) {\n\t\t\t\t\t\tlogger.info(\"RoutingAgent {} succeeded on retry attempt {}. Routed to sub-agent: {}\",\n\t\t\t\t\t\t\t\trootAgent.name(), attempt, decisionValue);\n\t\t\t\t\t}\n\t\t\t\t\treturn decisionValue;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Invalid agent name, store for next retry\n\t\t\t\t\tlastInvalidDecision = decisionValue;\n\t\t\t\t\tlogger.warn(\"RoutingAgent {} attempt {}/{} returned invalid agent name: {}\",\n\t\t\t\t\t\t\trootAgent.name(), attempt, maxRetries, decisionValue);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tif (attempt == maxRetries) {\n\t\t\t\t\t// Last attempt failed, rethrow the exception\n\t\t\t\t\tlogger.error(\"RoutingAgent {} failed on final attempt {}/{}\", rootAgent.name(), attempt, maxRetries, e);\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t\tlogger.warn(\"RoutingAgent {} attempt {}/{} encountered an error, will retry\", rootAgent.name(), attempt, maxRetries, e);\n\t\t\t}\n\t\t}\n\n\t\t// All retries exhausted\n\t\tthrow new IllegalStateException(\n\t\t\t\tString.format(\"Failed to get valid decision after %d retries. Last invalid decision: %s\",\n\t\t\t\t\t\tmaxRetries, lastInvalidDecision));\n\t}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/node/RoutingEdgeAction.java#L203-L239","documentation":"RoutingEdgeAction.getDecisionWithRetry logs this warning each time an LLM routing attempt returns a decision that is not a valid sub-agent name, storing it as lastInvalidDecision for the retry feedback loop. If all retries exhaust, the final failure escalates (exception or fallback depending on code path).","triggerScenarios":"decisionValue parses the LLM response but the value is not among the sub-agent names, on any attempt up to maxRetries; the message includes the attempt number, max, and the invalid name.","commonSituations":"Model returns 'END'/'none'/explanatory text instead of an agent name; agent list changed but prompt/cache stale; model hallucinating names from similar tasks; non-JSON wrapping like 'Decision: researcher'.","solutions":["Make the routing prompt strict: return exactly one name from the enumerated list","Add parsing that strips wrappers like 'Decision:' or JSON fences before validation","Increase maxRetries and verify error feedback is appended to the retry messages","Fall back to a default agent instead of failing when all attempts are invalid"],"exampleFix":"// before\nString decision = llmResponse.trim(); // 'Decision: researcher' -> invalid\n// after\nString decision = llmResponse.replaceAll(\"(?i)^decision:\\\\s*\", \"\").trim(); // 'researcher' -> valid","handlingStrategy":"retry","validationCode":"String d = normalize(rawResponse);\nif (!subAgents.stream().map(Agent::name).toList().contains(d)) { /* append corrective feedback and retry */ }","typeGuard":"static boolean isKnownAgentName(String s, List<Agent> agents) { return s != null && agents.stream().anyMatch(a -> a.name().equals(s)); }","tryCatchPattern":"try { String d = getDecisionWithRetry(state); } catch (Exception e) { if (e is last-retry failure) { routeToDefaultAgent(); } else { throw e; } }","preventionTips":["Normalize/strip LLM response wrappers ('Decision:', quotes, JSON) before validating","Keep the sub-agent list in the prompt synchronized with the actual registered agents","Define an explicit default/fallback route instead of exhausting retries into an exception"],"tags":["routing","invalid-decision","llm-output","retry"],"backgroundTag":"invalid-enum-value","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}