{"record":{"id":"7ad19c0bc46dbe65","repo":"alibaba/spring-ai-alibaba","slug":"routing-flow-requires-root-agent-to-be-a-flowagent","errorCode":null,"errorMessage":"Routing flow requires root agent to be a FlowAgent","messagePattern":"Routing flow requires root agent to be a FlowAgent","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/strategy/RoutingGraphBuildingStrategy.java","lineNumber":160,"sourceCode":"\t}\n\n\t/**\n\t * Validates routing-specific configuration requirements.\n\t * @param config the configuration to validate\n\t * @throws IllegalArgumentException if validation fails\n\t */\n\tprivate void validateRoutingConfig(FlowGraphBuilder.FlowGraphConfig config) {\n\t\tif (config.getSubAgents() == null || config.getSubAgents().isEmpty()) {\n\t\t\tthrow new IllegalArgumentException(\"Routing flow requires at least one sub-agent\");\n\t\t}\n\n\t\tif (config.getChatModel() == null) {\n\t\t\tthrow new IllegalArgumentException(\"Routing flow requires a ChatModel for decision making\");\n\t\t}\n\n\t\t// Ensure root agent is a FlowAgent for input key access\n\t\tif (!(config.getRootAgent() instanceof FlowAgent)) {\n\t\t\tthrow new IllegalArgumentException(\"Routing flow requires root agent to be a FlowAgent\");\n\t\t}\n\t}\n\n}\n","sourceCodeStart":142,"sourceCodeEnd":165,"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/strategy/RoutingGraphBuildingStrategy.java#L142-L165","documentation":"validateRoutingConfig in RoutingGraphBuildingStrategy throws when the root agent is not a FlowAgent — input-key access and routing merge semantics depend on FlowAgent, so other root types are rejected.","triggerScenarios":"Building a routing flow with a root agent that is a plain BaseAgent or other non-FlowAgent implementation; validateRoutingConfig runs during buildCoreGraph or validateConfig.","commonSituations":"Wrapping a routing graph with a custom root; constructing FlowGraphConfig manually with the wrong root type; refactoring that changed the root's class hierarchy.","solutions":["Use a FlowAgent subclass (e.g. RoutingAgent) as the root agent","Ensure the factory that creates the root returns a FlowAgent","Extend FlowAgent if a custom root implementation is required"],"exampleFix":"// before\nAgent root = new BaseAgentImpl(\"root\");\n// after\nRoutingAgent root = RoutingAgent.builder().chatModel(model).subAgents(a, b).build();","handlingStrategy":"validation","validationCode":"if (!(rootAgent instanceof FlowAgent)) {\n    throw new IllegalStateException(\"Routing root must be a FlowAgent\");\n}","typeGuard":"static boolean isValidRoutingRoot(Agent a) { return a instanceof FlowAgent; }","tryCatchPattern":null,"preventionTips":["Use RoutingAgent.builder() to construct routing roots","Avoid wrapping routing graphs with non-FlowAgent custom roots","Test root agent type when composing flows"],"tags":["java","agent-framework","routing","validation"],"backgroundTag":"invalid-argument-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"}