Join Node
The Join node is a generic N-input barrier. It waits until its upstream nodes settle according to join_mode, bundles their outputs per aggregation, and optionally feeds the bundle into a skill before cascading downstream.
Unlike the name might suggest, Join is not paired to any specific Fan-out — it is a plain N-input merge point you can use anywhere you have multiple parallel branches converging.
When to use
Section titled “When to use”- Multiple independent branches of work need to finish before the next step (e.g. gather research from three sources, then write a summary).
- You want to aggregate per-item outputs from a Fan-out — drop a Join after the fan-out and use
aggregation: arrayormerge. - You need a weaker sync than “all branches succeed” — e.g. continue as soon as the first returns (
join_mode: any) or when a majority is in.
Configuration
Section titled “Configuration”| Field | Description |
|---|---|
aggregation | How upstream outputs are bundled. array (default) wraps them as { _items, _sources, _total, _completed, _failed }; merge does a shallow key merge of object-typed outputs. |
join_mode | When the barrier releases. all (default), any, or majority. |
on_failure | fail_all (default) fails the join if any upstream failed; ignore continues with whatever succeeded; collect passes failures through. |
skill_id / skill_version_id (optional) | If set, the aggregated input is passed to this skill instead of auto-completing. Useful when you need an LLM to synthesize the branch outputs. |
Behavior
Section titled “Behavior”- Readiness is checked against
join_mode:all— every non-revision upstream must be in a terminal state.any— at least one upstream is completed and approved.majority— more than half of upstreams are completed and approved.
- Once ready, the Join bundles upstream outputs per
aggregationinto the input data, attaching_items(or merged keys),_sources,_total,_completed,_failed. - If any upstream failed and
on_failure === "fail_all", the Join is recorded asfailedand cascade stops. - Otherwise:
- If a skill is configured, the Join is inserted as
pendingwith the aggregated input, and runs on the assigned minion. - If no skill is configured, the Join auto-completes with the bundle as both input and output, and cascade continues.
- If a skill is configured, the Join is inserted as
Validation rules
Section titled “Validation rules”join_mode, if set, must be one ofall,any,majority.aggregation, if set, must be one ofarray,merge,pick_first.
Example
Section titled “Example”flowchart LR A["Skill: research-a"] --> J(("Join")) B["Skill: research-b"] --> J C["Skill: research-c"] --> J J --> Sum["Skill: summarize"]With aggregation: array, summarize receives _items as a three-element list in the order of the incoming edges.