{"record":{"id":"5337ad7c5980b0ef","repo":"apache/dolphinscheduler","slug":"cannot-find-task-pre","errorCode":null,"errorMessage":"\"Cannot find task: \" + pre","messagePattern":"\"Cannot find task: \" \\+ pre","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/graph/WorkflowGraph.java","lineNumber":129,"sourceCode":"                .stream()\n                .map(TaskDefinition::getName)\n                .forEach(taskDefinition -> {\n                    if (predecessors.containsKey(taskDefinition) || successors.containsKey(taskDefinition)) {\n                        throw new IllegalArgumentException(\"The task \" + taskDefinition + \" is already exists\");\n                    }\n                    predecessors.put(taskDefinition, new ArrayList<>());\n                    successors.put(taskDefinition, new ArrayList<>());\n                });\n    }\n\n    private void addTaskEdge(List<WorkflowTaskRelation> workflowTaskRelations) {\n        for (WorkflowTaskRelation workflowTaskRelation : workflowTaskRelations) {\n            long pre = workflowTaskRelation.getPreTaskCode();\n            long post = workflowTaskRelation.getPostTaskCode();\n            if (pre > 0 && post > 0) {\n\n                if (!taskDefinitionCodeMap.containsKey(pre)) {\n                    throw new IllegalArgumentException(\"Cannot find task: \" + pre);\n                }\n                if (!taskDefinitionCodeMap.containsKey(post)) {\n                    throw new IllegalArgumentException(\"Cannot find task: \" + post);\n                }\n                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                }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/graph/WorkflowGraph.java#L111-L147","documentation":"addTaskEdge validates each WorkflowTaskRelation: if the relation has a positive preTaskCode, the code must exist in the graph's task code map, otherwise the edge would point at a task the graph does not contain. It throws this IllegalArgumentException naming the missing pre-task code.","triggerScenarios":"Constructing WorkflowGraph with workflowTaskRelations whose getPreTaskCode() is > 0 but not present among the passed task definitions' codes.","commonSituations":"Relations referencing a task definition deleted from the workflow (orphaned edges in t_ds_workflow_task_relation); partial task list passed while the full relation set is used; task definition failed to save but relation did.","solutions":["Reconcile t_ds_workflow_task_relation against t_ds_task_definition and remove relations whose pre/post task codes have no definition","Load the task definitions from the same source/snapshot as the relations so they are consistent","Before constructing the graph, filter relations whose pre or post codes are not in the task list and fix the definition data","Catch IllegalArgumentException at construction to surface the inconsistent workflow definition for repair"],"exampleFix":"// before\nnew WorkflowGraph(taskDefinitions, relations); // relations reference deleted task 999\n// after\nSet<Long> codes = taskDefinitions.stream().map(TaskDefinition::getCode).collect(Collectors.toSet());\nList<WorkflowTaskRelation> valid = relations.stream()\n        .filter(r -> r.getPreTaskCode() <= 0 || codes.contains(r.getPreTaskCode()))\n        .filter(r -> r.getPostTaskCode() > 0 && codes.contains(r.getPostTaskCode()))\n        .collect(Collectors.toList());\nWorkflowGraph g = new WorkflowGraph(taskDefinitions, valid); // fix orphaned rows in DB too","handlingStrategy":"validation","validationCode":"Set<Long> codes = taskDefinitions.stream().map(TaskDefinition::getCode).collect(Collectors.toSet());\nList<WorkflowTaskRelation> broken = relations.stream()\n        .filter(r -> r.getPreTaskCode() > 0 && !codes.contains(r.getPreTaskCode()))\n        .collect(Collectors.toList());\nif (!broken.isEmpty()) throw new IllegalStateException(\"Dangling pre-task codes: \" + broken);","typeGuard":null,"tryCatchPattern":"try {\n    WorkflowGraph graph = new WorkflowGraph(taskDefinitions, relations);\n} catch (IllegalArgumentException e) {\n    log.error(\"Workflow relations reference missing tasks: {}\", e.getMessage());\n    throw new WorkflowDefinitionCorruptException(e);\n}","preventionTips":["Delete relations when deleting a task definition (cascade cleanup)","Load definitions and relations from the same transaction/snapshot","Add FK-like integrity checks between relation rows and definition rows","Validate workflow integrity after import/export operations"],"tags":["workflow-graph","task-relation","dangling-edge"],"backgroundTag":"resource-not-found","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"}