conductor-oss / conductor-oss/javascript-sdk

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

Offen Anfängerfreundlich
#135 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
TypeScript
Sterne
58
Forks
20
Ø Merge
1 T. 13 Std.
Gemergte PRs (30 T.)
7

Beschreibung

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

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Beginne in forkJoin.ts bei forkTaskJoin() und untersuche, wie generateJoinTask() joinOn liefert. Lies dann den bestehenden Fall in factory.test.ts um Zeile 141 und führe diesen Test aus. Fertig ist es, wenn der generierte JOIN, sofern vorhanden, auf die abschließende Fork-Task verweist, während leere Branches ein leeres joinOn beibehalten und der Test das korrigierte Verhalten widerspiegelt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
backend-api-design
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
78/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.