All nodes/Logic & Flow/Iteration
Filter
Iterates over the JSON array from the ED port 'Input'. Runs a subgraph for each element; the value on the end port must be strictly a bool. On true the source element is kept in the output array; on false it is dropped. Order is preserved. The node result is the filtered array.
Type in the graph: filter
ExecSubgraph
An error branch can be enabled (expose_error_output) to handle failures on their own path.
Ports can be split into separate execution and data handles.
Try it
Keeping elements that pass a test
The body answers yes or no for an element, and the node keeps only the elements that passed.
- Execute + Data
Runs as pasted
When to use it
Reach for this node when part of an array has to be kept as it is: orders above a threshold, mails with an attachment, rows a model judged relevant. When elements have to be transformed, use map; when no result is needed, use for_each. A test computed straight from the data is shorter as Jinja filters in a template or as one code_javascript node; the loop is worth it when a model or an external service makes the decision.
How it works
input (Array) carries the array and the run trigger. item (Start) opens the body, end
(End) closes it. The body runs for every element, and the value on end is read as “keep or
drop”. The output array holds the source element, not what the body returned, and the
order is preserved. The node’s result is the filtered array, {{ nodes.<id>.output }}.
The value on end has to be a real boolean. A template such as
{{ inputs.input.score > 5 }} works: it yields True or False. The strings "true" and
"yes", the number 1 and an empty string do not — the iteration fails with a message
naming the element index and what actually arrived.
“Include index” and “Parallel execution” behave as in map: with the index on, item
carries {<item key>: value, index: N}, and parallel mode schedules iterations concurrently
while their bodies still run under a shared lock.
Common mistakes
- The body returns something other than a boolean — most often a template yielding text
or the string
"true". Write the comparison entirely inside{{ }}. - Trying to change the element. The value on
endis only a verdict; for transformed elements usemap(filter first, then map, when both are needed). - An object on the input instead of an array. Put a
templatewith{{ inputs.input.items | tojson }}in front of the loop. - An open body. An edge out of
itemand an edge intoendare both required. - A loop inside a loop is rejected by the validator: sequence the loops, or move the
inner walk into
code_javascript. - An edge leading out of the body runs on every iteration; build the rest of the graph
from
completed(Done). - One failed iteration stops the loop and no filtered array is returned.
Inputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Arrayinput | Execute + Dataexecute_data | — | Run trigger and array payload (JSON array or string encoding an array). |
Itemend | Execute + Dataexecute_data | — | End of subgraph for one item; return value from inner graph. |
Outputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Resultcompleted | Execute + Dataexecute_data | — | |
Itemitem | Execute + Dataexecute_data | — |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
Include indexinclude_index | boolean | false | When true, each iteration passes a dict {item_key: element, index: n} on the item port. When false, the item port carries the array element value directly (no wrapper dict). |
Item keyitem_variable | string | item | Key for the current element in the payload dict (with index) on the item port. shown when include_index = true |
Max concurrencymax_concurrency | integer | 10 | Maximum parallel subgraph runs when parallel_execution is enabled. |
Parallel executionparallel_execution | boolean | false | Schedule subgraph iterations concurrently; each run still holds a global lock so inner nodes see a consistent payload (map/filter only). |
Shared fields
Every node has these three — the platform adds them, not the node author.
expose_error_output— When enabled, show an execution output to connect nodes that run if this step fails.split_ports_in— Show separate execution and data input handles instead of one combined port.split_ports_out— Show separate execution and data output handles instead of one combined port.