Skip to main content
Apragya AI
Docs · AI & Automation

Branching, conditions, loops: pipeline control flow

Decision points, switch-cases, loops, and parallel execution. Common patterns and the pitfalls that cost real runs.

Most useful pipelines need control flow - branch on this, loop over that, fan out to three things in parallel. The canvas gives you four node types for this: condition, switch, loop, parallel. This guide walks each, plus the patterns we've seen go wrong on tenant pipelines and how to avoid them.

Condition (if/else)

The simplest branch. Pick a field on the run's state (like an invoice amount), pick a comparison (greater than, equal to, matches), and connect the two outgoing edges to what should happen next. Use for binary decisions: "under threshold?", "new customer?", "requires legal review?".

Switch (multi-way)

When you have more than 2-3 branches, switch beats chained conditions. Express the cases as a list of (match, target_node) pairs; the platform picks the first match. A default branch catches anything unmatched.

Loop (for-each + while)

  • for-each: iterate over a list in the run state; the child sub-pipeline runs once per item with $.item bound
  • while: re-run a sub-pipeline until a condition flips false (rare - usually a code-smell that you should restructure)
  • Both require a max_iterations guardrail - the platform refuses to publish a loop without one

Parallel (fan-out fan-in)

Run N child nodes simultaneously, gather their outputs, continue when all complete. Useful when child nodes are independent (querying three different systems for the same record). Aggregation strategy is configurable: first-success, all-success, majority, or custom merge function.

A real example combining all four

Inbound vendor invoice -> condition (is this a known vendor?) -> if yes -> parallel (PO lookup, GRN lookup, tax-code lookup) -> rule (compose the line-by-line match decision) -> switch (status = matched/disputed/needs_review) -> matched -> http_call (post to ERP). Real Invoice Reviewer pipelines roughly match this shape; tenants customise the leaves.

Loop budget is the number-one source of runaway pipeline cost. A for-each over an unbounded list with an agent_call inside burns AI Credits fast. Cap max_iterations at a value that matches your real expected list size, and set a per-iteration timeout so a slow inner step can't drag the loop forever.

Patterns that go wrong

  • Deeply nested conditions - past 3 levels deep, the diagram is unreadable. Refactor to switch or sub-pipeline
  • Loop with side effects - state mutations inside a loop are hard to reason about; prefer building up a list in a rule node then writing once after the loop
  • Parallel with shared writes - two parallel branches writing to the same record race. Use the platform's optimistic-lock helper (db.update with expected_version) or serialise the writes

Need help building this? Talk to a real engineer

← All docs
Ask Vippy anything