apache/dolphinscheduler · error · IllegalArgumentException
"The task " + taskDefinition + " is already exists"
Error message
"The task " + taskDefinition + " is already exists"
What it means
addTaskNodes initializes the predecessor/successor adjacency lists for every task name in the graph. If a task name already has an entry, the task is being added twice and the graph would be corrupt, so it throws this IllegalArgumentException.
Source
Thrown at dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/graph/WorkflowGraph.java:115
TaskDefinition taskDefinition = taskDefinitionCodeMap.get(taskCode);
if (taskDefinition == null) {
throw new IllegalArgumentException("Cannot find task: " + taskCode);
}
return taskDefinition;
}
@Override
public List<TaskDefinition> getAllTaskNodes() {
return new ArrayList<>(taskDefinitionMap.values());
}
private void addTaskNodes(List<TaskDefinition> taskDefinitions) {
taskDefinitions
.stream()
.map(TaskDefinition::getName)
.forEach(taskDefinition -> {
if (predecessors.containsKey(taskDefinition) || successors.containsKey(taskDefinition)) {
throw new IllegalArgumentException("The task " + taskDefinition + " is already exists");
}
predecessors.put(taskDefinition, new ArrayList<>());
successors.put(taskDefinition, new ArrayList<>());
});
}
private void addTaskEdge(List<WorkflowTaskRelation> workflowTaskRelations) {
for (WorkflowTaskRelation workflowTaskRelation : workflowTaskRelations) {
long pre = workflowTaskRelation.getPreTaskCode();
long post = workflowTaskRelation.getPostTaskCode();
if (pre > 0 && post > 0) {
if (!taskDefinitionCodeMap.containsKey(pre)) {
throw new IllegalArgumentException("Cannot find task: " + pre);
}
if (!taskDefinitionCodeMap.containsKey(post)) {
throw new IllegalArgumentException("Cannot find task: " + post);
}View on GitHub (pinned to 02eac45a1b)
Solutions
- Ensure task names are unique across the workflow's task definitions before constructing the graph
- Deduplicate the input list by name (or fix upstream so duplicate definitions are not produced)
- If intentionally re-adding tasks, clear or rebuild the WorkflowGraph instead of mutating it
- Check the workflow definition in t_ds_task_definition for duplicate name rows
Example fix
// before
List<TaskDefinition> tasks = loadTasks(); // may contain duplicates
WorkflowGraph g = new WorkflowGraph(tasks, relations);
// after
List<TaskDefinition> unique = tasks.stream()
.collect(Collectors.toMap(TaskDefinition::getName, t -> t, (a, b) -> a))
.values().stream().collect(Collectors.toList());
WorkflowGraph g = new WorkflowGraph(unique, relations); Defensive patterns
Strategy: validation
Validate before calling
Set<String> names = new HashSet<>();
for (TaskDefinition t : taskDefinitions) {
if (!names.add(t.getName())) throw new IllegalStateException("Duplicate task name: " + t.getName());
} Try / catch
try {
WorkflowGraph graph = new WorkflowGraph(taskDefinitions, relations);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("is already exists")) log.error("Duplicate task in graph: {}", e.getMessage());
throw e;
} Prevention
- Enforce unique task names per workflow at save/import time
- Deduplicate task lists before building graphs in tests or utilities
- Rebuild WorkflowGraph instances rather than incrementally adding tasks
- Add a unique index on (workflow code, task name) in the definition store
When it happens
Trigger: Constructing a WorkflowGraph whose List<TaskDefinition> contains two definitions with the same name (streamed through TaskDefinition::getName). Internally this is reachable after the duplicate-code/name checks at lines 51-58 only if distinct names are impossible — in practice it fires on duplicate-name inputs when the earlier name check was bypassed (e.g. differing codes but the same name reaching addTaskNodes via different call paths).
Common situations: Duplicated task definitions with different codes but identical names in the workflow definition list; calling an overloaded constructor or add path twice with overlapping task lists; hand-built graphs in tests adding the same task twice.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "Duplicate task code: " + taskDefinition.getCode() + " in th
- remote.logging.google.cloud.storage.bucket.name is blank
- remote.logging.oss.bucket.name is empty
- data: %s should be a validate data string - yyyy-MM-dd HH:mm
- The date must not be null
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/3706bb27b85d3291.
Report an issue: GitHub.