{"record":{"id":"1cb1dac9da0ae266","repo":"alibaba/spring-ai-alibaba","slug":"invalid-params","errorCode":"INVALID_PARAMS","errorMessage":"content_type","messagePattern":"content_type","errorType":"error_code","errorClass":"BizException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/agent/BasicAgentExecutor.java","lineNumber":333,"sourceCode":"\t\tif (StringUtils.isNotBlank(config.getInstructions())\n\t\t\t\t&& !MessageRole.SYSTEM.getValue().equals(chatMessages.get(0).getRole().getValue())) {\n\t\t\tMessage message = buildInstructions(context, config.getInstructions());\n\t\t\tmessages.add(message);\n\t\t}\n\n\t\tfor (ChatMessage chatMessage : chatMessages) {\n\t\t\tMessage message = null;\n\t\t\tswitch (chatMessage.getRole()) {\n\t\t\t\tcase SYSTEM -> message = buildInstructions(context, String.valueOf(chatMessage.getContent()));\n\t\t\t\tcase USER -> {\n\t\t\t\t\tif (chatMessage.getContentType() == ContentType.TEXT) {\n\t\t\t\t\t\tmessage = new UserMessage(String.valueOf(chatMessage.getContent()));\n\t\t\t\t\t}\n\t\t\t\t\telse if (chatMessage.getContentType() == ContentType.MULTIMODAL) {\n\t\t\t\t\t\tmessage = buildMultimodelMessage(chatMessage.getContent());\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow new BizException(ErrorCode.INVALID_PARAMS.toError(\"content_type\",\n\t\t\t\t\t\t\t\tchatMessage.getContentType().getValue() + \"not supported\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase ASSISTANT -> message = new AssistantMessage(String.valueOf(chatMessage.getContent()));\n\t\t\t}\n\n\t\t\tmessages.add(message);\n\t\t}\n\n\t\treturn messages;\n\t}\n\n\t/**\n\t * Builds system instructions message\n\t * @param context Agent context\n\t * @param instructions System instructions\n\t * @return Message instance\n\t */","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/agent/BasicAgentExecutor.java#L315-L351","documentation":"RoutingNode's apply() gives the LLM up to DEFAULT_MAX_RETRIES chances to produce a routing decision whose agent names all match configured subagents. When all retries fail, it tries createFallbackCommand(state, messages); if no fallback agent is configured, the last exception from getDecisionWithRetry is rethrown, surfacing this exhausted-retries condition as a routing failure in the graph.","triggerScenarios":"LLM repeatedly returns agent names that are not in the subagent list (or empty lists) for all retry attempts AND RoutingAgent was built without a fallback agent, so createFallbackCommand returns null and the underlying exception propagates from apply().","commonSituations":"Subagent names mismatched or renamed after the router prompt was written; LLM (or weak model) ignoring the instruction and inventing agent names; prompt/instruction ambiguity; model returning structured output that fails parsing on every attempt; deployments with no fallback configured for production robustness.","solutions":["Configure a fallback agent on the RoutingAgent so exhausted retries degrade gracefully instead of throwing","Verify the agent names the LLM is returning match exactly the names() of registered subagents","Improve the routing instruction: list available agents explicitly and give examples of valid answers","Use a stronger/more capable model for the routing step","Increase DEFAULT_MAX_RETRIES if failures are marginal"],"exampleFix":"// before\nRoutingAgent agent = RoutingAgent.builder()\n    .name(\"router\")\n    .subAgents(List.of(plannerAgent, coderAgent))\n    .model(chatModel)\n    .build();\n// after\nRoutingAgent agent = RoutingAgent.builder()\n    .name(\"router\")\n    .subAgents(List.of(plannerAgent, coderAgent))\n    .model(chatModel)\n    .fallbackAgent(generalAssistantAgent) // handles exhausted retries\n    .build();","handlingStrategy":"fallback","validationCode":"// before building the agent, assert every name referenced in the instruction is registered\nSet<String> names = subAgents.stream().map(Agent::name).collect(java.util.stream.Collectors.toSet());\nif (names.isEmpty()) throw new IllegalStateException(\"RoutingAgent needs at least one subagent\");\nif (fallbackAgent == null) log.warn(\"RoutingAgent has no fallback; exhausted retries will throw\");","typeGuard":null,"tryCatchPattern":"try {\n    graph.invoke(inputs);\n} catch (Exception e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"exhausted routing retries\")) {\n        // degrade: route to a default agent or requeue for human handling\n        routeToDefaultAgent(inputs);\n    } else { throw e; }\n}","preventionTips":["Always configure a fallbackAgent for production routing agents","Keep subagent names stable and mirrored verbatim in the routing instruction","Test routing with your target model before deploying; log rejected decisions","Consider a stronger model for the routing step"],"tags":["routing-agent","retry-exhausted","invalid-decision","llm-output"],"backgroundTag":"retry-exhausted","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"}