conductor-oss/conductor · error · TerminateWorkflowException

No dynamic tasks could be created for the Workflow: %s, Dyna

Error message

No dynamic tasks could be created for the Workflow: %s, Dynamic Fork Task: %s

What it means

Thrown when getTasksToBeScheduled() for a dynamic fork task returns null or an empty list. This means the decider could not produce any schedulable tasks for the dynamic fork task definition — the task name/type may be invalid, the task definition may not exist in metadata, or a duplicate reference name was detected among existing tasks. The message includes the workflow short string and the dynForkTask, and if a duplicate reference name exists among IN_PROGRESS or terminal tasks, that is appended.

Source

Thrown at core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java:248

                                    .map(TaskModel::getReferenceTaskName)
                                    .filter(
                                            refTaskName ->
                                                    refTaskName.equals(
                                                            dynForkTask.getTaskReferenceName()))
                                    .findAny();

                    // Construct an informative error message
                    String terminateMessage =
                            "No dynamic tasks could be created for the Workflow: "
                                    + workflowModel.toShortString()
                                    + ", Dynamic Fork Task: "
                                    + dynForkTask;
                    if (existingTaskRefName.isPresent()) {
                        terminateMessage +=
                                " attempted to create a duplicate task reference name: "
                                        + existingTaskRefName.get();
                    }
                    throw new TerminateWorkflowException(terminateMessage);
                }

                mappedTasks.addAll(forkedTasks);
                // Get the last of the dynamic tasks so that the join can be performed once this
                // task is
                // done
                TaskModel last = forkedTasks.get(forkedTasks.size() - 1);
                joinOnTaskRefs.add(last.getReferenceTaskName());
            }
        }

        // From the workflow definition get the next task and make sure that it is a JOIN task.
        // The dynamic fork tasks need to be followed by a join task
        WorkflowTask joinWorkflowTask =
                workflowModel
                        .getWorkflowDefinition()
                        .getNextTask(workflowTask.getTaskReferenceName());

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Register the referenced TaskDef via POST /api/metadata/taskdefs if it does not exist.
  2. Ensure every dynamic fork task has a unique taskReferenceName — avoid collisions with existing tasks.
  3. Check for typos in the task type or name in the dynamic fork input payload.
  4. If using generated reference names, ensure the generation logic produces unique values (include an index or hash).

Example fix

// before — duplicate ref name collision
"forkedTasks": [
  { "name": "http_task", "taskReferenceName": "task_0" },
  { "name": "http_task", "taskReferenceName": "task_0" }
]

// after — unique ref names
"forkedTasks": [
  { "name": "http_task", "taskReferenceName": "task_0" },
  { "name": "http_task", "taskReferenceName": "task_1" }
]
Defensive patterns

Strategy: validation

Validate before calling

// Verify TaskDefs exist and ref names are unique before fork
for (WorkflowTask forkTask : dynForkTasks) {
    if (metadataDAO.getTaskDef(forkTask.getName()) == null
            && !systemTaskRegistry.isSystemTask(forkTask.getType())) {
        throw new IllegalStateException("TaskDef not found: " + forkTask.getName());
    }
}
Set<String> refNames = dynForkTasks.stream()
    .map(WorkflowTask::getTaskReferenceName)
    .collect(Collectors.toSet());
if (refNames.size() != dynForkTasks.size()) {
    throw new IllegalStateException("Duplicate taskReferenceName in dynamic fork");
}

Prevention

When it happens

Trigger: A dynamic fork task references a task name that has no registered TaskDef in metadata. A dynamic fork task's taskReferenceName collides with an existing IN_PROGRESS or terminal task in the same workflow. The task type in the dynamic fork definition is invalid or unregistered.

Common situations: Task definition was deleted from metadata after the workflow was designed. Two dynamic fork tasks generate the same taskReferenceName (e.g., deterministic naming from non-unique input keys). The forked task type string has a typo or uses a deprecated name.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/ca28eca34a97a94d. Report an issue: GitHub.