{"record":{"id":"6f42a21d7463d6b6","repo":"alibaba/spring-ai-alibaba","slug":"routing-sub-agents-must-be-baseagent-for-merge-sup-6f42a2","errorCode":null,"errorMessage":"Routing sub-agents must be BaseAgent for merge support","messagePattern":"Routing sub-agents must be BaseAgent for merge support","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/spring-ai-alibaba-starter-agentscope/src/main/java/com/alibaba/cloud/ai/agent/agentscope/flow/AgentScopeRoutingGraphBuildingStrategy.java","lineNumber":80,"sourceCode":"\t\tString routingNodeName = rootAgent.name() + \"_routing\";\n\t\tgraph.addNode(routingNodeName, node_async((state) -> Map.of()));\n\n\t\tString firstBeforeModelNode = routingNodeName;\n\t\tif (!beforeModelHooks.isEmpty()) {\n\t\t\tfirstBeforeModelNode = connectBeforeModelHookEdges(graph, routingNodeName, beforeModelHooks);\n\t\t}\n\t\tgraph.addEdge(rootAgent.name(), firstBeforeModelNode);\n\n\t\tString routingExitNode = routingNodeName;\n\t\tif (!afterModelHooks.isEmpty()) {\n\t\t\troutingExitNode = connectAfterModelHookEdges(graph, routingNodeName, afterModelHooks);\n\t\t}\n\n\t\tString mergeNodeName = rootAgent.name() + \"_merge\";\n\t\tList<BaseAgent> baseAgentList = new ArrayList<>(config.getSubAgents().size());\n\t\tfor (Agent subAgent : config.getSubAgents()) {\n\t\t\tif (!(subAgent instanceof BaseAgent)) {\n\t\t\t\tthrow new IllegalArgumentException(\"Routing sub-agents must be BaseAgent for merge support\");\n\t\t\t}\n\t\t\tbaseAgentList.add((BaseAgent) subAgent);\n\t\t}\n\t\tgraph.addNode(mergeNodeName, node_async(new AgentScopeRoutingMergeNode(model, baseAgentList)));\n\n\t\tMap<String, String> edgeRoutingMap = new HashMap<>();\n\t\tfor (Agent subAgent : config.getSubAgents()) {\n\t\t\tcom.alibaba.cloud.ai.graph.agent.flow.strategy.FlowGraphBuildingStrategy.addSubAgentNode(subAgent, graph);\n\t\t\tedgeRoutingMap.put(subAgent.name(), subAgent.name());\n\t\t\tgraph.addEdge(subAgent.name(), mergeNodeName);\n\t\t}\n\t\tgraph.addEdge(mergeNodeName, this.exitNode);\n\n\t\tAgentScopeRoutingNode routingNode = new AgentScopeRoutingNode(model, rootAgent, config.getSubAgents(), systemPrompt);\n\t\tgraph.addParallelConditionalEdges(\n\t\t\t\troutingExitNode,\n\t\t\t\tAsyncMultiCommandAction.node_async(routingNode),\n\t\t\t\tedgeRoutingMap);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-boot-starters/spring-ai-alibaba-starter-agentscope/src/main/java/com/alibaba/cloud/ai/agent/agentscope/flow/AgentScopeRoutingGraphBuildingStrategy.java#L62-L98","documentation":"AgentScopeRoutingGraphBuildingStrategy.buildCoreGraph() converts every configured sub-agent into a BaseAgent so the routing merge node can merge their outputs. If a sub-agent is not an instance of BaseAgent (e.g. a wrapper or custom Agent implementation), the merge machinery cannot handle it and an IllegalArgumentException is thrown while building the graph.","triggerScenarios":"Building a routing flow whose FlowGraphConfig.subAgents list contains an Agent implementation that does not extend BaseAgent.","commonSituations":"Mixing agents from different frameworks/wrappers into an AgentScope routing flow; using a custom Agent subclass that doesn't extend BaseAgent; passing placeholder/decorator agents; library upgrade changed the agent base class hierarchy.","solutions":["Ensure all sub-agents passed to the routing flow extend BaseAgent (AgentScope agent hierarchy).","Wrap or replace foreign Agent implementations with BaseAgent-compatible equivalents.","If a custom agent type is required, extend BaseAgent so routing/merge works.","Log/inspect the sub-agents list before building to find the offending instance type."],"exampleFix":"// before\nList<Agent> subs = List.of(new MyCustomAgent()); // does not extend BaseAgent\nbuilder.subAgents(subs);\n// after\nList<Agent> subs = List.of(new AgentScopeSubAgent()); // extends BaseAgent\nbuilder.subAgents(subs);","handlingStrategy":"type-guard","validationCode":"// Java: verify all sub-agents extend BaseAgent before building\nList<Agent> bad = subAgents.stream()\n    .filter(a -> !(a instanceof BaseAgent))\n    .toList();\nif (!bad.isEmpty()) {\n    throw new IllegalStateException(\"Non-BaseAgent sub-agents: \" + bad.stream().map(a -> a.getClass().getName()).toList());\n}","typeGuard":"// Java\nstatic boolean isMergeCompatible(Agent a) {\n    return a instanceof BaseAgent;\n}\n// use: subAgents.stream().allMatch(FlowGuard::isMergeCompatible)","tryCatchPattern":"// Java\ntry {\n    flow = AgentScopeRoutingFlow.builder()...build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"must be BaseAgent\")) {\n        LOGGER.error(\"Sub-agent types: {}\", subAgents.stream().map(Object::getClass).toList());\n    }\n    throw e;\n}","preventionTips":["Only mix agents from the AgentScope BaseAgent hierarchy in routing flows.","Keep a factory method that constructs sub-agents to guarantee the base type.","Add a build-time assertion validating sub-agent types in integration tests."],"tags":["agentscope","routing","type-mismatch","graph-building","illegal-argument"],"backgroundTag":"type-mismatch","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"}