Union node
The Union node concatenates rows from every upstream connected to its in port into a single downstream stream. Useful when the same downstream logic should apply to rows arriving from multiple Sources or upstream branches.
When to use
- You have two or more Sources of the same shape (customer rows from Salesforce plus customer rows from a Postgres export) and want to run one Load, one Message, or one Compute over the combined stream.
- You need to funnel rows from disjoint transformation branches back into a single downstream sink.
- The rows do not need to be correlated or matched (that's what Join is for) — they just need to be concatenated.
Ports
| Port | Direction | Kind | Cardinality | Notes |
|---|---|---|---|---|
in | in | data | many | Every incoming edge lands on this port. Fan-in supported. |
out | out | data | one | Concatenated rows. |
error | out | control | one | Fires on validation failures. |
notify | out | control | one | Notification policy port. |
Configuration
- Column policy. One of
nullFill,drop, orrename.nullFill(default) — output row set has the union of every upstream's column set. Any row missing a column receivesnullfor that column. Currently the only policy that reliably works with a singleinport atcardinality: many.drop— output row set has the intersection of every upstream's column set. Any column not present in every upstream is dropped. Documented gap: today's single-port design collapses all upstreams into one bucket, so the intersection reduces to the whole set anddropsilently no-ops. Track the follow-up in the multi-source workflows runbook.rename— apply a per-upstreamcolumnRenamesmap before merging. Same single-port limitation asdrop.
- columnRenames.
{ [upstreamNodeId]: { fromCol: toCol } }per-upstream rename map used when the policy isrename.
Runtime behaviour
- Cross-source ordering. When Union sits downstream of two or more Sources, the runtime treats Union as a fan-in barrier. Union is skipped during every per-source pass and dispatched once, after every reachable Source has completed, from a run-scoped buffer of rows destined for the node. This is what makes a two-Source Union actually see rows from both sides.
- Row order. Deterministic per manifest edge order — the order in which the upstream edges were authored on the canvas.
- Chunked pumps upstream still stream through Union's buffer; the barrier does not force full-materialization for single-source flows (barrier only triggers when Union's reachable-source set has more than one entry).
Failure modes
dropreturns the whole set — see the runbook's Known gaps entry for the single-port limitation. UsenullFilland drop the unwanted columns in a downstream Transform or Compute.renamenever applies — same root cause; documented gap.