Skip to content

DynamicFork auto-join has empty joinOn — JOIN task completes immediately without waiting for dynamic branches #158

Description

@nthmost-orkes

Summary

DynamicFork's companion JoinTask is constructed with zero arguments, producing empty joinOn: []. When added to a workflow, the JOIN task completes immediately — before any dynamic fork branches finish.

Tested against: Conductor OSS 3.32.0-rc.9

Root Cause

// Conductor/Definition/TaskType/DynamicFork.cs:32
public DynamicFork(string taskReferenceName, ...) : base(...)
{
    this.Join = new JoinTask(taskReferenceName + "_join");  // no joinOn args
    ...
}

JoinTask(string taskReferenceName, params WorkflowTask[] joinOn) — called with zero WorkflowTask args → JoinOn = new List<string>() on the companion join task.

When the user adds dynamicFork.Join to the workflow definition, the JOIN task has joinOn: []. The server's Join executor evaluates joinOn.stream().allMatch(...) — on an empty stream, allMatch returns true immediately — the JOIN transitions to COMPLETED without waiting for any dynamic fork branches.

Impact

Any workflow that uses DynamicFork.Join to obtain the join task will have a join that completes immediately. Dynamic tasks spawned by the fork run in the background while the rest of the workflow proceeds as if the fork were done.

Cross-SDK Confirmation

Same root cause as:

The server behavior (empty joinOn → immediate completion) was live-confirmed against Conductor OSS 3.32.0-rc.9 in those audits.

Fix

Require callers to supply the join-on tasks, or expose it as a settable property that must be populated before use:

public DynamicFork(string taskReferenceName, string forkTasksParameter,
    string forkTasksInputsParameter, params WorkflowTask[] joinOn)
{
    this.Join = new JoinTask(taskReferenceName + "_join", joinOn);
    ...
}

For dynamic forks, the tasks are determined at runtime, so the client cannot auto-infer joinOn. The user must explicitly pass the tasks to wait for (typically the dynamic task reference names they configure at workflow design time).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions