Skip to main content

Conditions (Branch Node)

The Branch node (also called the Condition node) routes workflow execution based on a Python expression. It has two output paths: True and False. Downstream nodes connected to each path only execute if the condition evaluates to that boolean value.


How Conditions Work

When execution reaches the Branch node:

  1. The condition expression is evaluated using Python
  2. If it evaluates to True → nodes connected to the True output run
  3. If it evaluates to False → nodes connected to the False output run
  4. The other path's nodes are skipped (shown as light gray on the canvas)

Condition Configuration

In the node inspector:

FieldDescription
ConditionPython expression (single expression, not statements)
LabelDisplay name on the canvas

The condition must be a valid Python expression that evaluates to a boolean (or truthy/falsy value).


Available Variables in Conditions

The condition expression has access to these variables:

VariableTypeDescription
outputstrOutput of the immediately upstream node
trigger_outputstrThe original trigger output ({{trigger.output}})
node_outputsdictAll completed node outputs: {"agent_name": "output_text"}

Condition Examples

String Checks

# Contains keyword
"error" in output.lower()

# Starts with
output.strip().startswith("{")

# Is a specific value
output.strip() == "approved"

# Length check
len(output) > 500

# Non-empty
bool(output.strip())

Numeric Conditions

# If the output is a number
float(output.strip()) > 0.8

# Compare extracted number
int(output.split()[0]) >= 100

JSON Output Parsing

Condition expressions are a restricted Python subset — no imports, no builtins, no arbitrary code. That means you can't parse JSON inside the condition itself.

When an upstream agent outputs JSON, extract the field first with a Transform node (JSONPath), then write a simple condition on the extracted value:

Agent (outputs JSON)
→ Transform JSONPath: $.severity → "high"
→ Condition output.strip() == "high"

This keeps conditions readable and robust:

output.strip() == "high" # simple, clear
output.strip().isdigit() # value-shape checks are fine
Shape the data before you branch

Do JSON extraction and reshaping in a Transform node, and keep Condition/Switch/Filter expressions limited to simple comparisons on plain values. There is no code-execution or JavaScript path in node expressions by design.

Multi-Source Conditions

Use node_outputs to check any upstream node's output, not just the immediate predecessor:

# Both agents must agree
"approved" in node_outputs["reviewer_1"].lower() and "approved" in node_outputs["reviewer_2"].lower()

# Either agent flagged an issue
"error" in node_outputs["analyzer"].lower() or "critical" in node_outputs["monitor"].lower()

# Cross-check two values
node_outputs["classifier"].strip() == node_outputs["verifier"].strip()

Always True / Always False

Useful for debugging or forcing a specific path:

True # Always routes to True path
False # Always routes to False path

Branch Node Patterns

Pattern 1: Severity Routing

Route based on analysis outcome:

Condition:

"critical" in node_outputs["log-analyzer"].lower()

Pattern 2: Length-Based Routing

Short content gets formatted differently than long content:

Condition:

len(output) > 1000

Pattern 3: Format Validation

Check if output is valid JSON before processing:

Condition:

(lambda s: (lambda d: True)(lambda: __import__('json').loads(s))())(output) if output.strip().startswith('{') else False

Better — have the extractor output "valid" or "invalid" and check:

output.strip() == "valid"

Pattern 4: Threshold-Based Gate

Only proceed if confidence is high enough:

Condition:

float(node_outputs["classifier"].strip()) > 0.85

True path: Continue processing (high confidence)
False path: Route to a human review queue

Pattern 5: Multi-Stage Approval

Chain multiple conditions for a multi-stage approval flow:

First Branch: "spam" not in output.lower()
True → Second Branch: len(output) > 100
True → Agent: publish
False → Agent: expand-content
False → Agent: mark-as-spam

Connecting Branch Outputs

The Branch node has two output handles:

  • Top handle = True path
  • Bottom handle = False path

To connect a path:

  1. Hover over the True (top) or False (bottom) handle on the branch node
  2. Drag to any downstream node
  3. Repeat for the other path (or leave it unconnected if you don't need it)
One path is fine

You don't have to connect both paths. If the True path leads to nodes but the False path isn't connected, a False result simply ends execution on that path. The workflow completes with whatever ran.


Nested Conditions

You can nest Branch nodes for complex logic:

When to Use Nested vs. Combined Conditions

Use nested branches when:

  • Each branch involves different downstream workflows
  • You want to handle each case with different agents
  • Readability on the canvas matters

Use combined condition when:

  • The logic is simple enough for one expression
  • condition_1 and condition_2 is easy to read

Rejoining After Branches

Branches are mutually exclusive — only the matched path runs; the other is skipped. To rejoin, simply connect both branch paths to the same downstream node. That node runs once, fed by whichever branch was active:

No dedicated merge node is needed: the skipped branch is marked skipped and the shared downstream node executes with the active branch's output.


Debugging Conditions

Condition evaluation errors

If the condition expression raises a Python exception, the Branch node fails. Check execution details for the error message.

Common errors:

  • ValueError: could not convert string to float — output isn't a number
  • json.JSONDecodeError — output isn't valid JSON
  • KeyError — JSON key doesn't exist in the output

Prevention: Add defensive coding:

# Safe float conversion
(lambda o: float(o) > 0.8 if o.replace('.','').isdigit() else False)(output.strip())

# Safe JSON access
__import__('json').loads(output).get("severity", "unknown") == "high"

Condition always takes wrong path

  1. Check the execution details → Branch node → see the resolved output value
  2. Test your condition logic: what does output actually contain?
  3. Check for whitespace: output.strip() == "approved" not output == "approved"

Seeing the condition result

In execution details, the Branch node shows:

  • The condition expression
  • The resolved output value used in evaluation
  • The condition result: True or False
  • Which path was taken