Blocks

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

The merge step in the Inspector 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_all collects 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 over payload["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 first mode 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_all keys are step ids. They are rename-stable, but check the actual ids in the Inspector before writing payload["…"] references.
  • first means 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; use wait_all or combine_array when more than one branch can be live.

Related

  • If and switch, the steps that create branches.
  • Loop for consuming combine_array output.
  • Reshape to filter or sort the combined list.