Merge
Fan two or more branches back into one payload in wait_all, combine_array, or first mode. How skipped branches are handled and the keys the output uses.
Fan-in: wire two or more branches into merge and they reconverge into one payload. The mode picks the output shape.
What it does
Every edge into a merge is a branch. When the run reaches the merge, it collects the output of each branch that actually ran, in the order the edges were wired, and reshapes them according to the mode. Nothing downstream of the merge runs until every live branch has finished, so a merge is also the simplest way to say "wait for all of these before continuing".
Branches that were skipped by an upstream if or switch don't take part. There is no timeout to configure: the engine knows which branches can still arrive, so a dead branch is simply absent rather than something to wait for.
Config
One choice: how the branches combine.
- Mode, one of three (default
wait_all): - wait_all: waits for every live branch; output is a map keyed
by upstream step id, so you can tell branches apart:
payload["stripe-1"]["ok"]. - combine_array:
{ "items": […], "count": n }in wiring order. Feed it to a loop or reshape. - first: the first live branch's payload passes through unchanged. The natural choice after an if/switch where only one branch survives.
Output
Three branches named stripe-1, hubspot-1 and sheet-1, each
emitting a small map, produce:
// wait_all
{ "stripe-1": { "ok": true, "customer_id": "cus_8" },
"hubspot-1": { "ok": true, "contact_id": 4411 },
"sheet-1": { "ok": true, "row": 17 } }
// combine_array
{ "items": [ { "ok": true, "customer_id": "cus_8" },
{ "ok": true, "contact_id": 4411 },
{ "ok": true, "row": 17 } ],
"count": 3 }
// first (when only stripe-1 ran)
{ "ok": true, "customer_id": "cus_8" }
Reference {{ payload.hubspot-1.contact_id }} after wait_all,
{{ payload.items }} or payload["items"] after combine_array,
and the branch's own fields after first. The step id in
wait_all is the id shown in the Inspector's step header, not
the display name.
Skipped branches
A branch a condition didn't fire never blocks the merge. It's
simply absent from the output (omitted key in wait_all, missing
item in combine_array). If every branch was skipped, the merge
and everything after it skip too.
Patterns
- Parallel enrichment: one webhook fans out to three lookups;
wait_allcollects all three, keyed, for one downstream report. - Rejoin after a branch: if/switch → per-case handling →
merge (
first) → shared tail (save, notify) written once. - Gather for a loop: several fetches →
combine_array→ loop overpayload["items"], so one body handles every source the same way. - Barrier: two independent writes that must both finish before
a notification goes out;
wait_all, then the notify step.
Gotchas
- In
firstmode the surviving branch's payload passes through as-is, so every branch must carry all the keys the shared tail references. A key present on one branch but missing on another fails only when the other branch runs. The build-time linter checks downstream refs against the union of the branches and flags keys only some of them carry. wait_allkeys are step ids. They are rename-stable, but check the actual ids in the Inspector before writingpayload["…"]references.firstmeans first in wiring order among the branches that ran, not first to finish. When two branches both run, the one whose edge was created first wins, which is rarely what you meant; usewait_allorcombine_arraywhen more than one branch can be live.