{"record":{"id":"a9a98a42bf27a9c5","repo":"alibaba/spring-ai-alibaba","slug":"cannot-convert-multicommand-with-multiple-nodes-to","errorCode":null,"errorMessage":"Cannot convert MultiCommand with multiple nodes to Command","messagePattern":"Cannot convert MultiCommand with multiple nodes to Command","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/action/MultiCommand.java","lineNumber":63,"sourceCode":"\t\tthis(gotoNodes, Map.of());\n\t}\n\n\t/**\n\t * Checks if this MultiCommand represents a single node (for backward compatibility).\n\t * @return true if there's only one node, false otherwise\n\t */\n\tpublic boolean isSingleNode() {\n\t\treturn gotoNodes.size() == 1;\n\t}\n\n\t/**\n\t * Converts a single-node MultiCommand to a regular Command.\n\t * @return a Command instance if this is a single node, otherwise throws an exception\n\t * @throws IllegalStateException if this MultiCommand contains multiple nodes\n\t */\n\tpublic Command toCommand() {\n\t\tif (!isSingleNode()) {\n\t\t\tthrow new IllegalStateException(\"Cannot convert MultiCommand with multiple nodes to Command\");\n\t\t}\n\t\treturn new Command(gotoNodes.get(0), update);\n\t}\n}\n\n","sourceCodeStart":45,"sourceCodeEnd":69,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/action/MultiCommand.java#L45-L69","documentation":"MultiCommand.toCommand() converts a MultiCommand to a single-target Command, which is only possible when exactly one goto node is present. With multiple goto nodes the conversion is ambiguous, so an IllegalStateException is thrown.","triggerScenarios":"Calling multiCommand.toCommand() on a MultiCommand constructed with two or more goto nodes (isSingleNode() returns false).","commonSituations":"Generic code paths that normalize any node result via toCommand() without checking multi-node commands; refactors where a previously single-target route started returning multiple branches.","solutions":["Call isSingleNode() before toCommand() and handle multi-target commands with the multi-node execution path","Use gotoNodes.get(0) explicitly only when discarding extra targets is intentional","Refactor the node to return Command when it only ever targets one node","Inspect the router logic if a single-target route unexpectedly returns multiple nodes"],"exampleFix":"// before\nCommand cmd = multiCommand.toCommand(); // throws for multiple nodes\n// after\nCommand cmd = multiCommand.isSingleNode()\n        ? multiCommand.toCommand()\n        : handleMultiTarget(multiCommand);","handlingStrategy":"type-guard","validationCode":"if (!multiCommand.isSingleNode()) { /* route via multi-node path */ }","typeGuard":"static Optional<Command> asSingleCommand(MultiCommand mc) {\n    return mc.isSingleNode() ? Optional.of(mc.toCommand()) : Optional.empty();\n}","tryCatchPattern":"try { cmd = mc.toCommand(); } catch (IllegalStateException e) { cmd = handleMulti(mc); }","preventionTips":["Check isSingleNode() before toCommand()","Keep node results typed: use Command for single targets, MultiCommand only when branching","Avoid generic toCommand() normalization in framework glue code"],"tags":["graph","routing","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}