Merge (core.merge)
Bring branches back together: append streams, join rows by a key, zip them by
position, or just wait for every branch to arrive. Up to 8 inputs (a…h).
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | append | combine_by_key | combine_by_position | wait_all | append | See behavior below. Combine modes always pair the first two inputs (a + b). |
number_of_inputs | 2–8 | 2 | How many inputs append/wait_all consume (and the canvas shows). |
key_a, key_b | string | id | combine_by_key only: the field to match on, per side. |
join | inner | left | outer | inner | combine_by_key only: what happens to unmatched rows. |
Behavior
append — every configured input's items, concatenated. Order is always
by input index then item index — never by which branch happened to finish
first, so runs are deterministic.
combine_by_key — an SQL-style join of inputs a and b:
a: {"id": 1, "name": "one"} {"id": 2, "name": "two"}
b: {"id": 2, "score": 20} {"id": 3, "score": 30}
inner → {"id": 2, "name": "two", "score": 20}
left → adds {"id": 1, "name": "one"} (unmatched a rows kept)
outer → adds {"id": 3, "score": 30} too (unmatched b rows kept)
combine_by_position — zips a and b pairwise: item 0 with item 0, 1 with
1, … down to the shorter side; leftover rows on the longer side are dropped.
wait_all — passes input a through untouched, but only after every
connected input has resolved. Use it as a synchronization gate ("don't
continue until both API calls finished").
On field collisions, b wins — combined json is {...a, ...b}. Binary
attachments merge the same way: a combined item carries both sides' files,
b's version winning a name clash.
A dead branch doesn't deadlock the merge. If one input's branch was fully filtered away or skipped, the merge fires on the inputs that did arrive (or is skipped itself if all inputs trace to dead branches).
Quirks & tips
- A hidden input is a dead input. Shrinking
number_of_inputswith an edge still wired to a now-hidden handle (inputcwith the count at 2) silently contributes nothing. Delete edges you no longer want. - Rows whose key is missing or
nullnever match incombine_by_key— they behave as unmatched (dropped underinner, kept underleft/outer). - Duplicate keys on the b side: first occurrence wins; later b rows with
the same key are only kept by an
outerjoin. combine_by_positiontruncates to the shorter side — check your counts if rows go missing.- Combined items'
paired_itemis a pair[a_index, b_index]into the flattened all-input view, so lineage survives the join.
Related
- IF / Switch — the nodes that split what Merge reunites.
- Filter — a fully-filtered branch upstream is the classic "why didn't my merge fire on b" answer (it did — on the inputs that existed).
- Loop Over Items — for batching rather than joining.