{"record":{"id":"6db1e0429cb7daef","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-create-parallel-node-action-for-target-6db1e0","errorCode":null,"errorMessage":"Failed to create parallel node action for target: ","messagePattern":"Failed to create parallel node action for target: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/internal/ParallelEdgeProcessor.java","lineNumber":238,"sourceCode":"\t\t\t}\n\n\t\t\t// Create a ParallelNode that executes all subgraphs in parallel\n\t\t\tvar parallelNode = new ParallelNode(sourceNodeId, convergenceNodeId, subGraphActions, subGraphNodeIds,\n\t\t\t\t\tkeyStrategyMap, compileConfig);\n\n\t\t\tnodeFactoriesUpdater.accept(parallelNode.id(), parallelNode.actionFactory());\n\t\t\tedgesUpdater.accept(sourceNodeId, new EdgeValue(parallelNode.id()));\n\t\t\tedgesUpdater.accept(parallelNode.id(), new EdgeValue(convergenceNodeId));\n\t\t} else {\n\t\t\t// Simple case: A->B->Z, A->C->Z - use ParallelNode\n\t\t\tvar targetList = validTargets;\n\n\t\t\tvar actions = targetList.stream()\n\t\t\t\t\t.map(target -> {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn nodeFactories.get(target.id()).apply(compileConfig);\n\t\t\t\t\t\t} catch (GraphStateException ex) {\n\t\t\t\t\t\t\tthrow new RuntimeException(\"Failed to create parallel node action for target: \"\n\t\t\t\t\t\t\t\t\t+ target.id() + \". Cause: \" + ex.getMessage(), ex);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.toList();\n\n\t\t\tvar actionNodeIds = targetList.stream().map(EdgeValue::id).toList();\n\n\t\t\tvar parallelNode = new ParallelNode(sourceNodeId, convergenceNodeId, actions, actionNodeIds,\n\t\t\t\t\tkeyStrategyMap, compileConfig);\n\n\t\t\tnodeFactoriesUpdater.accept(parallelNode.id(), parallelNode.actionFactory());\n\t\t\tedgesUpdater.accept(sourceNodeId, new EdgeValue(parallelNode.id()));\n\t\t\tedgesUpdater.accept(parallelNode.id(), new EdgeValue(convergenceNodeId));\n\t\t}\n\t}\n\n\t/**\n\t * Finds the convergence node where all parallel paths from the given start nodes meet.","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/internal/ParallelEdgeProcessor.java#L220-L256","documentation":"During advanced parallel edge processing, each parallel target's node factory is invoked to produce an Action. A GraphStateException from a target node factory is rethrown as a RuntimeException naming the failing target node id.","triggerScenarios":"nodeFactories.get(target.id()).apply(compileConfig) throws GraphStateException for one of the parallel branch targets — e.g. the node's action factory validates its inputs/edges and fails at compile time.","commonSituations":"Parallel fan-out to nodes whose action factories depend on state keys or edges that are missing; misdeclared node actions (async wrappers constructed incorrectly); recursionLimit/saver config mismatch in CompileConfig.","solutions":["Inspect the cause GraphStateException for the failing target id reported in the message.","Verify the node action factory for that target validates successfully with the supplied CompileConfig.","Check that the node is registered via addNode before being used as a parallel edge target.","Test each parallel branch node individually to find which factory throws."],"exampleFix":"// before: factory requires key not declared in state\nvar node = new AsyncNodeAction(state -> ...);\n// after: declare required key in the graph state schema\nKeyStrategyFactory keys = map -> { map.put(\"input\", new AppenderChannel()); ... };","handlingStrategy":"validation","validationCode":"// Confirm each parallel target exists and its action factory is constructible\nObjects.requireNonNull(nodeFactories.get(targetId), \"No factory for parallel target \" + targetId);","typeGuard":null,"tryCatchPattern":"try { compiled = graph.compile(config); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Failed to create parallel node action\")) { /* fix node reported after 'for target:' */ } }","preventionTips":["Register every fan-out target with addNode before wiring parallel edges","Ensure action factories' required state keys exist in the schema","Use async action adapters consistently","Compile at startup, not lazily at request time"],"tags":["parallel-execution","compile-time","node-action"],"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-14T05:17:10.506Z"}