How Nodes Read Input
Learn this once and it holds for every node in the palette.
The shape every node produces
A node's output always carries result, and carries _metadata
whenever the node has something to report:
{
"result": { "...": "the thing you care about" },
"_metadata": { "...": "supporting facts: counts, timestamps, topics" }
}
result is the payload — always there. _metadata is everything
about the payload: how many rows came back, which topic it arrived on,
how long it took. Nodes with nothing to report (Set, No-Op) omit it
rather than sending an empty one, so don't be surprised when a simple
node's output is just { "result": ... }.
This is why almost every path you write starts at result:
{{ $node["Read Tags"].result.temperature }}
{{ $node["Read Tags"]._metadata.count }}
The rule for reading
Every node that takes data from upstream asks one question — "what do I take?" — through one field, and that field defaults to the previous node's
result.
So when you drop a node that consumes data, look for its one input field. It is always there, it always accepts the same two syntaxes, and it is usually already filled in with the right answer.
The two syntaxes, everywhere
| You write | Means | Use it when |
|---|---|---|
result | the whole value from the node before this one | the common case |
result.rows | one field inside that value | the value is an object |
{{ $node["Fetch"].result.rows }} | reach any node by name | after a merge, or a fan-in, or to skip a node |
The plain path can only see the node immediately before. The {{ }}
form can reach anywhere — and it is the only form the designer's
autocomplete can help you with, so reach for it whenever you are unsure
what is available.
The field, node by node
| Node | Field | Default |
|---|---|---|
| Aggregate | Value Field | you must set it — a number has no safe default |
| Buffer | Item Field | result |
| Data Serializer | Input Field | result |
| File Extractor | Input Field | result |
| HTML Extract | Input | you must set it |
| Group By | Input Field | result |
| For Each | Source Expression | you must set it — an array has no safe default |
| UNS Publish Batch | Items | you must set it |
Where a node needs a particular number or array, it asks rather than guessing. Where taking the whole value is the sensible answer, it is already filled in.
The label is the field's name in plain English, and the five nodes that select a value all say the same thing — Value Field, Item Field, Input Field. Where a node's field is genuinely node-specific the label says so (HTML Input, Source Expression), because a generic label there would be less useful, not more consistent.
What you get back out
A node that collects things hands on values, so the next node reads the row directly:
{{ $node["Window"].result[3].id }}
not the row wrapped in anything. Two nodes are worth calling out:
-
Merge has no input field, because it combines every incoming branch rather than selecting one thing. It unwraps each branch for you.
-
End For-Each is the deliberate exception: it keeps each body node's full output, keyed by node name, so you can reach any node inside the loop:
{{ $node["End For-Each"].result[0]["Process"].result.name }}See For-Each Loop for the full LoopResult shape.
When a path is wrong
A path that does not resolve fails the node and names what it could not find, along with the keys that were actually there:
itemField "result.readng" not found in input — every node output is
{result, _metadata}, so a path starts at result
(available keys: _metadata, result)
That is deliberate. A node that quietly carried on with the wrong data would give you a confident wrong answer somewhere far downstream, and the run would look successful the whole way.
Run the node once and open its output in the node drawer. What you see there is exactly what the next node receives — paths you write against it will resolve.