Workflows
A workflow is a tree — one trigger, then a chain of steps that can branch, loop and route errors.
A GoRunner workflow is a recursive tree, not a free-form graph. One trigger starts the flow; each step points at the next; branches, loops and error paths nest whole sub-chains. The structure is always unambiguous — there is exactly one way execution can reach any step — which is what makes runs replayable, diffs readable, and AI-authored proposals safe to validate.
Anatomy
Every step has:
| Field | Meaning |
|---|---|
name | Stable identifier (lowercase_snake), unique in the flow. Expressions address steps by this name — renaming is a real change. |
displayName | The label people see on the canvas. |
type | PIECE, BRANCH, LOOP or CODE. |
pieceId / actionId | Which piece action runs (http / send_request). Structural steps use their built-ins: branch/evaluate, loop/loop_on_items, code/run_code. |
config | The action's input, validated against the piece's declared schema. Values may be literals or expressions. |
connectionId | Optional reference to a stored credential. |
Branches
A branch carries arms, each with a firstAction chain and conditions. Conditions are groups of rules — outer groups OR together, rules inside a group AND together — 40 typed operators (num_gt, text_contains, date_before, list_is_empty, …). The first arm whose conditions match runs; an Otherwise arm catches the rest. The Switch piece is the value-router variant: match one value against several cases.
Loops
Loop on Items takes a list-valued expression and runs its body once per item. Inside the body, {{loop.item}} and {{loop.index}} address the current element.
Per-step error handling
Each executable step declares what a failure means:
- Stop the run (default) — the run fails at this step.
- Continue — skip the failure and proceed.
- Run error steps — divert to the step's own error chain (
onErrorAction); the failure message is available as{{steps.<name>.error}}. The normal continuation is skipped and the run completes.
Steps also carry per-step retry and timeout settings, and the workflow itself has a wall-clock timeout and a concurrency limit (extra production triggers beyond the limit are refused with 429 CONCURRENCY_LIMIT, never silently queued forever).
Workflow-level extras
- Sub-flows — the Execute Workflow piece runs another workflow as a step, passing input as the child's trigger data and exposing its output. Depth-guarded.
- Error workflow — route any failure of this workflow to a handler flow (or have a handler subscribe itself with the Error Trigger; the two paths deduplicate — one failure, one handler run).
- Notes — sticky notes annotate the canvas without affecting execution.