Flow Studio
$input — Immediate Upstream Output
$input refers to the output of the node that connects directly into the current node's primary input port. It is the most convenient way to access upstream data in linear pipelines — the caller does not need to know the upstream node's ID.
What $input Contains
$input resolves to the value stored in ExecutionMemory.GetPreviousNodeOutput() for the current node. It is determined by the graph edge that connects to the primary input port of the current node.
| Scenario | $input Value |
|---|---|
| Linear pipeline — node B is connected to node A's output | Node A's output object |
| First node after the trigger | null — the trigger has no upstream node output |
| Node with multiple incoming edges (fan-in) | Output of the primary port connection — use $output.{nodeId} for the others |
| Node inside a sub-workflow | Output of the parent call node that invoked the sub-workflow |
Expression Examples
// Accessing a field from the immediately preceding node
$input.invoiceTotal
$input.customer.tierLevel
$input.lineItems[0].sku
// Using $input in a condition expression
$input.isApproved == true
$input.amount > 1000
// Mapping $input into a downstream node's config
{
"customerId": "{{$input.customerId}}",
"orderRef": "{{$input.referenceNumber}}"
}
$input vs. $output.{nodeId}
| Attribute | $input | $output.{nodeId} |
|---|---|---|
| Node ID required | No — always the immediately preceding node | Yes — must specify the exact nodeId |
| Resilience to reordering | Follows the edge — if you rewire the graph, $input updates automatically | Fixed to the named node — rewiring does not change it |
| Fan-in support | Limited — only reads primary port | Full — read any node by ID |
| Use in linear pipelines | Preferred — cleaner expressions | Verbose but explicit |
Null Handling
$input is null at the first node after a trigger. Use null-safe navigation or guard expressions when the first node can receive either trigger data or upstream node data depending on the workflow configuration.
// Null guard in condition
$input != null && $input.status == "active"
// Null coalescing (where supported by expression engine)
$input?.orderTotal ?? 0
// Use $json instead of $input at the first node
// CORRECT — at the first node, use $json for the trigger payload
$json.body.order.total
// WRONG — $input is null at the first node
$input.order.total // Returns null, causing downstream errors
$input changes meaning based on where the node is in the graph. The same expression
$input.customerId reads from a different upstream node depending on which node connects to the current node's input. This is a feature in linear pipelines but can be confusing if you move nodes. Use $output.{nodeId} when you need a stable reference that does not change with rewiring.