{"record":{"id":"eff485e16270dc7e","repo":"apache/dolphinscheduler","slug":"serious-error-graph-has-cycle","errorCode":null,"errorMessage":"serious error: graph has cycle ! ","messagePattern":"serious error: graph has cycle ! ","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/graph/DAG.java","lineNumber":340,"sourceCode":"    }\n\n    /**\n     * Only DAG has a topological sort\n     *\n     * @return topologically sorted results, returns false if the DAG result is a ring result\n     * @throws Exception errors\n     */\n    public List<Node> topologicalSort() throws Exception {\n        lock.readLock().lock();\n\n        try {\n            Map.Entry<Boolean, List<Node>> entry = topologicalSortImpl();\n\n            if (entry.getKey()) {\n                return entry.getValue();\n            }\n\n            throw new Exception(\"serious error: graph has cycle ! \");\n        } finally {\n            lock.readLock().unlock();\n        }\n    }\n\n    /**\n     * if tho node does not exist,add this node\n     *\n     * @param node node\n     * @param nodeInfo node information\n     */\n    private void addNodeIfAbsent(Node node, NodeInfo nodeInfo) {\n        if (!containsNode(node)) {\n            addNode(node, nodeInfo);\n        }\n    }\n\n    /**","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/graph/DAG.java#L322-L358","documentation":"DAG.topologicalSort() performs a topological ordering of the graph; if the underlying graph contains a directed cycle, no topological order exists and it throws Exception(\"serious error: graph has cycle ! \"). This usually indicates a malformed workflow dependency graph — in DolphinScheduler this should have been caught earlier by cycle detection, so it is treated as a serious invariant violation.","triggerScenarios":"Calling dag.topologicalSort() (directly or via dag.nodeList()) on a DAG<String, ...> whose edges contain a cycle, e.g. A->B, B->A, added via addEdge or addEdgeIfAbsent.","commonSituations":"Workflow definitions with circular task dependencies (task A depends on B and B on A) slipped past validation; custom code builds a DAG manually and adds a back edge; DAG used as a general-purpose graph without acyclicity checks.","solutions":["Detect the cycle before sorting: call dag.topologicalSortImpl() or check hasCycle-ish logic / use DagHelper to validate the workflow's dependencies and reject cyclic definitions.","Remove the circular dependency edge(s) from the input (fix task dependency configuration).","If you own the code, catch the Exception around topologicalSort() and surface a user-friendly 'circular dependency' error identifying the nodes involved."],"exampleFix":"// before\nList<Node> sorted = dag.topologicalSort(); // throws on cycles\n\n// after\nif (dag.hasCycle()) { // or try { dag.topologicalSort(); } catch (Exception e)\n    throw new WorkflowException(\"Workflow tasks contain a circular dependency, cannot sort\");\n}\nList<Node> sorted = dag.topologicalSort();","handlingStrategy":"try-catch","validationCode":"// Validate the workflow's dependency graph before building/sorting\nDAG<String, String, String> dag = DagHelper.buildDagGraph(tasks);\nif (dag.hasCycle()) { // or attempt topologicalSortImpl() and inspect the boolean\n    throw new WorkflowException(\"Circular dependency detected among tasks\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    List<Node> sorted = dag.topologicalSort();\n} catch (Exception e) {\n    throw new WorkflowException(\"Workflow task graph contains a cycle: \" + e.getMessage(), e);\n}","preventionTips":["Run cycle detection (DagHelper) when saving/importing workflow definitions so cyclic graphs never reach sort.","In the UI, prevent users from creating dependencies that loop back to upstream tasks.","Write unit tests for DAG construction with back-edge scenarios."],"tags":["graph","dag","cycle","topological-sort"],"backgroundTag":"internal-invariant-violation","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}