{"record":{"id":"f98ba5bc6a9d0a4a","repo":"apache/dolphinscheduler","slug":"the-task-relation-from-pre-to-post","errorCode":null,"errorMessage":"\"The task relation from \" + pre + \" to \" + post + \" is invalid\"","messagePattern":"\"The task relation from \" \\+ pre \\+ \" to \" \\+ post \\+ \" is invalid\"","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/graph/WorkflowGraph.java","lineNumber":152,"sourceCode":"                TaskDefinition preTask = checkNotNull(taskDefinitionCodeMap.get(pre), \"Cannot find task: \" + pre);\n                TaskDefinition postTask = checkNotNull(taskDefinitionCodeMap.get(post), \"Cannot find task: \" + pre);\n                List<String> predecessorsTasks = predecessors.get(postTask.getName());\n                if (predecessorsTasks.contains(preTask.getName())) {\n                    throw new IllegalArgumentException(\"The task relation from \" + preTask.getName() + \" to \"\n                            + postTask.getName() + \" is already exists\");\n                }\n                predecessorsTasks.add(preTask.getName());\n\n                List<String> successTasks = successors.get(preTask.getName());\n                if (successTasks.contains(postTask.getName())) {\n                    throw new IllegalArgumentException(\"The task relation from \" + preTask.getName() + \" to \"\n                            + postTask.getName() + \" is already exists\");\n                }\n                successTasks.add(postTask.getName());\n            }\n\n            if (pre <= 0 && post <= 0) {\n                throw new IllegalArgumentException(\"The task relation from \" + pre + \" to \" + post + \" is invalid\");\n            }\n\n        }\n    }\n}\n","sourceCodeStart":134,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/graph/WorkflowGraph.java#L134-L158","documentation":"A WorkflowTaskRelation is only meaningful if at least one endpoint is set: pre > 0 or post > 0. When both preTaskCode and postTaskCode are <= 0 the relation points nowhere, so addTaskEdge throws this IllegalArgumentException with the raw code values.","triggerScenarios":"Constructing WorkflowGraph with a relation row where both getPreTaskCode() and getPostTaskCode() are 0 (or negative) — the default values of an unsaved/never-populated WorkflowTaskRelation.","commonSituations":"Relation rows inserted with default codes because the referenced task definitions failed to save; hand-written or generated relation JSON with placeholder zeros; deserialization of an empty relation object.","solutions":["Filter out relations where pre <= 0 && post <= 0 before constructing the graph","Find and delete zero-code rows in t_ds_workflow_task_relation","Ensure relation creation always sets a valid postTaskCode (a task with no predecessor still has post > 0 and pre <= 0, which is legal)","Catch IllegalArgumentException at construction to flag workflows with corrupt relation data"],"exampleFix":"// before\nnew WorkflowGraph(tasks, relations); // contains relation {pre:0, post:0}\n// after\nList<WorkflowTaskRelation> usable = relations.stream()\n        .filter(r -> r.getPreTaskCode() > 0 || r.getPostTaskCode() > 0)\n        .collect(Collectors.toList());\nWorkflowGraph g = new WorkflowGraph(tasks, usable);","handlingStrategy":"validation","validationCode":"boolean hasEmptyRelation = relations.stream()\n        .anyMatch(r -> r.getPreTaskCode() <= 0 && r.getPostTaskCode() <= 0);\nif (hasEmptyRelation) throw new IllegalStateException(\"Relation with both codes <= 0 present\");","typeGuard":null,"tryCatchPattern":"try {\n    WorkflowGraph graph = new WorkflowGraph(taskDefinitions, relations);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"is invalid\")) log.error(\"Zero-code relation row found\");\n    throw e;\n}","preventionTips":["Filter default/unsaved WorkflowTaskRelation objects before saving","Ensure relation creation always assigns a valid postTaskCode","Clean zero-code rows from the relation table after failed saves","Treat pre<=0 as 'no predecessor' (legal) but never allow both to be <=0"],"tags":["workflow-graph","invalid-relation","dag"],"backgroundTag":"invalid-argument-value","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"}