{"record":{"id":"75e5699f9479b7dc","repo":"alibaba/spring-ai-alibaba","slug":"workflow-config-invalid-75e569","errorCode":"WORKFLOW_CONFIG_INVALID","errorMessage":"Workflow must contain at least one start node with in-degree 0","messagePattern":"Workflow must contain at least one start node with in-degree 0","errorType":"error_code","errorClass":"BizException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/workflow/runtime/WorkflowExecuteManager.java","lineNumber":419,"sourceCode":"\t\t// Create a temporary WorkflowConfig to reuse the validation logic\n\t\tWorkflowConfig tempConfig = new WorkflowConfig();\n\t\ttempConfig.setNodes(nodes);\n\t\ttempConfig.setEdges(edges);\n\t\tDirectedAcyclicGraph<String, Edge> graph = constructGraph(tempConfig);\n\n\t\t// Check connectivity\n\t\tSet<String> sourceNodes = graph.vertexSet()\n\t\t\t.stream()\n\t\t\t.filter(nodeId -> graph.incomingEdgesOf(nodeId).isEmpty())\n\t\t\t.collect(Collectors.toSet());\n\n\t\tSet<String> sinkNodes = graph.vertexSet()\n\t\t\t.stream()\n\t\t\t.filter(nodeId -> graph.outgoingEdgesOf(nodeId).isEmpty())\n\t\t\t.collect(Collectors.toSet());\n\n\t\tif (sourceNodes.isEmpty()) {\n\t\t\tthrow new BizException(ErrorCode.WORKFLOW_CONFIG_INVALID\n\t\t\t\t.toError(\"Workflow must contain at least one start node with in-degree 0\"));\n\t\t}\n\t\tif (sinkNodes.isEmpty()) {\n\t\t\tthrow new BizException(ErrorCode.WORKFLOW_CONFIG_INVALID\n\t\t\t\t.toError(\"Workflow must contain at least one end node with out-degree 0\"));\n\t\t}\n\n\t\t// Check if all nodes are reachable from source nodes\n\t\tSet<String> reachableFromSource = new HashSet<>();\n\t\tfor (String sourceNode : sourceNodes) {\n\t\t\treachableFromSource.addAll(findReachableNodes(graph, sourceNode));\n\t\t}\n\t\tif (!reachableFromSource.equals(graph.vertexSet())) {\n\t\t\tthrow new BizException(ErrorCode.WORKFLOW_CONFIG_INVALID\n\t\t\t\t.toError(\"There are nodes that cannot be reached from start nodes\"));\n\t\t}\n\n\t\t// Check if all nodes can reach sink nodes","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/workflow/runtime/WorkflowExecuteManager.java#L401-L437","documentation":"During graph construction in WorkflowExecuteManager.constructGraph, the directed graph of workflow nodes must contain at least one source node (in-degree 0) to serve as the start. If every node has incoming edges, there is no entry point and WORKFLOW_CONFIG_INVALID is thrown.","triggerScenarios":"Saving/running a workflow whose edges form a cycle covering all nodes, or whose start node incorrectly has an incoming edge (e.g. an edge drawn into the Start node), leaving zero nodes with in-degree 0.","commonSituations":"Hand-edited or imported workflow JSON with a wrong edge list; connecting an end/loop node back to the start node creating a full cycle; a misconfigured loop workflow without an explicit start; migration bugs that reindex node ids so edges point at the wrong nodes.","solutions":["Open the workflow in the editor and confirm exactly one Start node exists with no incoming edges.","Remove any edge that points into the start node or disconnect nodes so a node with in-degree 0 exists.","Break cycles: restructure loops using the loop node or conditional edges instead of wiring the last node back to the start.","Validate the workflow definition JSON (nodes/edges) after import or migration before running."],"exampleFix":"// before\nedges: [{source: \"end\", target: \"start\"}] // cycle, no in-degree-0 node\n// after\nedges: [] // start node has no incoming edges","handlingStrategy":"validation","validationCode":"boolean hasSource = graph.vertexSet().stream().anyMatch(n -> graph.incomingEdgesOf(n).isEmpty());\nif (!hasSource) throw new IllegalStateException(\"workflow needs a start node with no incoming edges\");","typeGuard":null,"tryCatchPattern":"try {\n    manager.execute(context);\n} catch (BizException e) {\n    if (\"WORKFLOW_CONFIG_INVALID\".equals(e.getCode())) { /* fix graph topology before running */ }\n}","preventionTips":["Validate the graph (exactly one in-degree-0 start node) at save/publish time, not only at run time.","Never draw edges into the Start node; use conditional nodes for re-entry logic instead of cycles.","Re-run validation after importing or hand-editing workflow JSON."],"tags":["workflow","graph-validation","cycle","configuration"],"backgroundTag":"schema-validation-failed","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"}