conductor-oss / conductor-oss/javascript-sdk

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

Aperta Adatta ai principianti
#135 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug
Lingua principale
TypeScript
Stelle
58
Fork
20
Merge medio
1g 13h
PR unite (30g)
7

Descrizione

## 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

```typescript
// 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:

```typescript
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.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
backend-api-design
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
78/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.