n8n If node: conditions and examples
Updated 2026-10-21 · 5 min read
The n8n If node splits a workflow into two paths based on conditions you define. Items that match go out of the true output, the rest out of false. Most of the problems people have with it come from data types, not logic. This page lists every comparison, shows how to combine them, and covers the cases where Switch or Filter is the better choice.
How the If node evaluates items
The If node checks each item separately. If 10 items come in and 3 have status = "paid", three items leave on true and seven on false, in the same run. Both outputs can fire, and the nodes on each branch run for their own items.
This differs from an if statement in code that runs once. When you need a single decision for the whole batch (for example "is the list empty?"), aggregate first or use a Code node that returns one item.
Adding conditions
Each condition has three parts: a value (usually an expression like {{ $json.status }}), a data type with an operator, and a value to compare against. Select Add condition for more.
Comparisons by data type
From the If node docs:
| Type | Operators |
|---|---|
| String | exists, does not exist, is empty, is not empty, is equal to, is not equal to, contains, does not contain, starts with, does not start with, ends with, does not end with, matches regex, does not match regex |
| Number | exists, does not exist, is empty, is not empty, is equal to, is not equal to, is greater than, is less than, is greater than or equal to, is less than or equal to |
| Date & Time | exists, does not exist, is empty, is not empty, is equal to, is not equal to, is after, is before, is after or equal to, is before or equal to |
| Boolean | exists, does not exist, is empty, is not empty, is true, is false, is equal to, is not equal to |
| Array | exists, does not exist, is empty, is not empty, contains, does not contain, length equal to / not equal to / greater than / less than / greater than or equal to / less than or equal to |
| Object | exists, does not exist, is empty, is not empty |
The Switch node uses the same list, so anything you learn here carries over.
AND and OR
With two or more conditions, the dropdown between them sets the logic:
- AND: the item must meet all conditions.
- OR: the item must meet at least one.
The condition builder applies one combinator to all conditions, so you can't mix AND and OR in one node (the Filter docs say the same for its identical builder). For (A AND B) OR C, either chain two If nodes, or write the whole test as one Boolean condition:
{{ ($json.country === 'DE' && $json.total > 100) || $json.vip === true }}
Set the type to Boolean and the operator to is true.
Examples
Route paid orders
- Value:
{{ $json.status }} - String > is equal to
paid
Skip items without an email
- Value:
{{ $json.email }} - String > is not empty
Items with an empty or missing email go to false. Leave the false output unconnected and they stop there.
Only recent records
- Value:
{{ $json.createdAt }} - Date & Time > is after
{{ $now.minus({ days: 7 }) }}
Check an HTTP status code
After an HTTP Request node with Never Error and Include Response Headers and Status turned on:
- Value:
{{ $json.statusCode }} - Number > is equal to
404
True branch creates the record, false branch updates it.
Webhook validation
Right after a Webhook node:
{{ $json.body.email }}String > matches regex^[^@\s]+@[^@\s]+$- AND
{{ $json.body.amount }}Number > is greater than0
False branch goes to a Respond to Webhook node with status 400.
Type pitfalls
Most "the If node is wrong" reports are type mismatches.
| Problem | Example | Fix |
|---|---|---|
| Number arrives as string | Query parameter "10" compared with Number > is greater than 9 |
{{ Number($json.query.limit) }} |
| Boolean as string | "true" from a form |
Compare as String is equal to true, or convert |
| Date as text | "21/10/2026" |
Parse it first with the Date & Time node or Luxon in an expression |
| Field missing vs empty | undefined vs "" |
Use exists for missing, is empty for empty |
| Case | "Paid" vs "paid" |
Lowercase in the expression: {{ $json.status.toLowerCase() }} |
The Switch and Filter docs describe a Less Strict Type Validation option that makes n8n try to convert values to the operator's type. Converting explicitly in the expression is easier to debug.
If, Switch, Filter or code?
| Need | Use |
|---|---|
| Two paths | If |
| Three or more paths | Switch |
| Drop items that don't match, keep one path | Filter |
| Complex condition used once | One Boolean condition with an expression |
| Condition that needs several lookups or loops | Code node returning a flag, then If |
Joining branches again
After an If node the two branches are separate. If they should continue into the same nodes, connect both outputs to the next node or put a Merge node in between. In workflows that use the current (v1) execution order, only the branch that received items runs; the legacy v0 order could execute both branches when a Merge node followed an If node, and the docs keep a note about it for old workflows.
From Pipedream If/Else
Pipedream's If/Else operator (marked beta in its docs) maps to the n8n If node, and Pipedream's Filter operator maps to the n8n Filter node. In a Pipedream export, the steps inside if/else branches are stored in a separate deployments field, which a naive conversion drops. Our converter reads that field and rebuilds branches as If and Switch nodes where it can, but it marks every workflow with branches for manual review, because branch conditions need a check by hand. Details: Pipedream control flow to n8n.
See which of your workflows use branches with the free report, or test a single code step with the code step checker. The report and 1 workflow are free. Full export: $3 per workflow, $19 minimum — coming soon.
Not affiliated with Pipedream or n8n.
FAQ
- How many outputs does the n8n If node have?
- Two: true and false. Items that meet the conditions go to true, the rest to false. For more than two routes use the Switch node.
- How do I combine conditions in the n8n If node?
- Add several conditions and choose AND (all must match) or OR (any can match) in the dropdown between them.
- Why does my If node send a number to the false branch?
- The value is probably a string, for example a query parameter "10". Depending on settings the node fails with a wrong type error or routes the item unexpectedly. Convert it first, for example with Number() in an expression.
- Does the If node run once per item?
- Yes. Each item is evaluated on its own, so one run can send some items to true and others to false.
- What is the difference between If and Filter in n8n?
- If keeps both groups and routes them to two outputs. Filter has one output and drops items that don't match.
Related
Sources
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.switch
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.filter
- https://docs.n8n.io/build/flow-logic/split-with-conditionals
- https://pipedream.com/docs/workflows/building-workflows/control-flow/ifelse