{"record":{"id":"0a248988f266b90f","repo":"alibaba/spring-ai-alibaba","slug":"subgraph-not-support-start-with-parallel-branches","errorCode":null,"errorMessage":"subgraph not support start with parallel branches yet!","messagePattern":"subgraph not support start with parallel branches yet!","errorType":"exception","errorClass":"GraphStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/ProcessedNodesEdgesAndConfig.java","lineNumber":91,"sourceCode":"\n\t\t\tvar sgWorkflow = subgraphNode.subGraph();\n\n            // Merges keyStrategies of this subgraph.\n            subgraphNode.keyStrategies().forEach(keyStrategyMap::putIfAbsent);\n            // Merges the keyStrategyMap aggregated from recursive subgraphs.\n            ProcessedNodesEdgesAndConfig processedSubGraph = process(sgWorkflow, config);\n            processedSubGraph.keyStrategyMap().forEach(keyStrategyMap::putIfAbsent);\n\n\t\t\tStateGraph.Nodes processedSubGraphNodes = processedSubGraph.nodes;\n\t\t\tStateGraph.Edges processedSubGraphEdges = processedSubGraph.edges;\n\n\t\t\t//\n\t\t\t// Process START Node\n\t\t\t//\n\t\t\tvar sgEdgeStart = processedSubGraphEdges.edgeBySourceId(START).orElseThrow();\n\n\t\t\tif (sgEdgeStart.isParallel()) {\n\t\t\t\tthrow new GraphStateException(\"subgraph not support start with parallel branches yet!\");\n\t\t\t}\n\n\t\t\tvar sgEdgeStartTarget = sgEdgeStart.target();\n\n\t\t\tif (sgEdgeStartTarget.id() == null) {\n\t\t\t\tthrow new GraphStateException(format(\"the target for node '%s' is null!\", subgraphNode.id()));\n\t\t\t}\n\n\t\t\tvar sgEdgeStartRealTargetId = subgraphNode.formatId(sgEdgeStartTarget.id());\n\n\t\t\t// Process Interruption (Before) Subgraph(s)\n\t\t\tinterruptsBefore = interruptsBefore.stream()\n\t\t\t\t\t.map(interrupt -> Objects.equals(subgraphNode.id(), interrupt) ? sgEdgeStartRealTargetId\n\t\t\t\t\t\t\t: interrupt)\n\t\t\t\t\t.collect(Collectors.toUnmodifiableSet());\n\n\t\t\tvar edgesWithSubgraphTargetId = edges.edgesByTargetId(subgraphNode.id());\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/ProcessedNodesEdgesAndConfig.java#L73-L109","documentation":"When a node wraps a subgraph, ProcessedNodesEdgesAndConfig.process validates the subgraph's structure. If the subgraph's START edge is a parallel (fan-out) edge, a GraphStateException is thrown because subgraph entry with parallel branches is not supported.","triggerScenarios":"Adding a node via addNode(id, subGraph) where subGraph's START connects through addConditionalEdges/addParallelBranches (parallel fan-out from START).","commonSituations":"Reusing a top-level workflow as a subgraph when that workflow starts with a parallel fan-out; refactoring a graph's start into parallel branches and embedding it elsewhere.","solutions":["Introduce a single-entry dispatcher node: START -> dispatcher, then branch from dispatcher with parallel edges.","Keep parallel fan-out out of the subgraph's START edge; move branching after the first node.","Inline the parallel nodes into the parent graph instead of embedding as a subgraph."],"exampleFix":"// before\nsubGraph.addEdge(START, \"a\", \"b\"); // parallel from START\nparent.addNode(\"sub\", subGraph);\n// after\nsubGraph.addEdge(START, \"entry\");\nsubGraph.addParallelBranch(List.of(\"a\", \"b\"), \"entry\");\nparent.addNode(\"sub\", subGraph);","handlingStrategy":"validation","validationCode":"Edge sgEdgeStart = subCompiled.getGraph().edgeBySourceId(START).orElseThrow(); if (sgEdgeStart.isParallel()) throw new IllegalStateException(\"Subgraph must not start with parallel branches\");","typeGuard":null,"tryCatchPattern":"try { parent.addNode(\"sub\", subGraph); compiled = parent.compile(cfg); } catch (GraphStateException e) { log.error(\"Subgraph structure unsupported: {}\", e.getMessage()); }","preventionTips":["Design subgraphs with a single deterministic entry node from START.","Validate subgraph structure with a compile test before embedding.","Replace START-level parallel fan-out with an explicit dispatcher node."],"tags":["subgraph","graph-compile","parallel-branch"],"backgroundTag":"unsupported-operation","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"}