forkTaskJoin() generates JOIN with empty joinOn — join completes immediately without waiting for branches

Open Beginner friendly
#135 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript

Research direction

Start in forkJoin.ts at forkTaskJoin() and inspect how generateJoinTask() supplies joinOn. Then read the existing case in factory.test.ts around line 141 and run that test. Done means the generated JOIN references the final fork task when present, while empty branches retain an empty joinOn, and the test reflects the corrected behavior.

Written by the indexing model from the issue text.

Description

bug

Summary

forkTaskJoin() creates a JOIN task with joinOn: [] (empty array). The Conductor
server's JOIN executor uses joinOn.stream().allMatch(...) to check if all listed tasks
are terminal — on an empty stream, allMatch short-circuits to true immediately,
so the JOIN transitions to COMPLETED without waiting for any fork branches.

Server baseline

Conductor 3.32.0-rc.9

Root cause

// forkJoin.ts:22
export const forkTaskJoin = (
  taskReferenceName: string,
  forkTasks: TaskDefTypes[],
  optional?: boolean
): [ForkJoinTaskDef, JoinTaskDef] => [
  forkTask(taskReferenceName, forkTasks),
  generateJoinTask({ name: `${taskReferenceName}_join`, optional }),
  //                 ^^^  no joinOn passed — defaults to []
];

generateJoinTask defaults to joinOn: []. The existing test (factory.test.ts:141)
explicitly asserts joinOn: [], locking in the broken behavior.

Live evidence

Tested against Conductor OSS 3.32.0-rc.9 with a 10-second WAIT task as the fork branch:

After 2 seconds:
  forkTaskJoin (joinOn=[])          → join=COMPLETED  wait_branch=IN_PROGRESS  ← BUG
  manual joinOn=['wait_branch']     → join=IN_PROGRESS  wait_branch=IN_PROGRESS  ← CORRECT

The JOIN with joinOn: [] reached COMPLETED while the fork branch was still running.

Impact

Any workflow that uses forkTaskJoin() will have a JOIN that completes immediately
when first evaluated. Fork branches continue running concurrently, but the downstream
workflow does not wait for them.

Proposed fix

Infer joinOn from the last task reference name in the fork branch:

export const forkTaskJoin = (
  taskReferenceName: string,
  forkTasks: TaskDefTypes[],
  optional?: boolean
): [ForkJoinTaskDef, JoinTaskDef] => {
  const joinOn = forkTasks.length > 0
    ? [forkTasks[forkTasks.length - 1].taskReferenceName]
    : [];
  return [
    forkTask(taskReferenceName, forkTasks),
    generateJoinTask({ name: `${taskReferenceName}_join`, joinOn, optional }),
  ];
};

factory.test.ts should also be updated to assert joinOn: ['forkTaskJoin'] (the last
task's ref name) rather than joinOn: [].

Related

Discovered during systematic SDK audit against Conductor OSS 3.32.0-rc.9.
The multi-branch limitation of forkTask() is separately tracked in #94.

Dominant language
TypeScript
Stars
58
Forks
20
Avg merge
1d 13h
Merged PRs (30d)
7

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from conductor-oss/javascript-sdk

All issues in conductor-oss/javascript-sdk

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.