Documentation · Playgrounds
How the Workflow Builder works: context, types, and execution
By Cicero Valentim · updated November 8, 2026
Back to toolWorkflow Builder
Build, on a canvas, a flow that chains lab tools (JSON, crypto, regex, dates…) and run it for real in the browser. Every node has typed inputs and outputs, and the editor points out configuration errors before you run anything.
Everything runs in your browser. Saved workflows live in this device's
localStorage and only leave it when you export the JSON.
Two graphs on one canvas
The canvas shows two different relations between nodes, and the Order / Data / Order + data switch picks which ones are drawn:
| Line | What it means | How to create it |
|---|---|---|
| Solid, square handle | Execution order: what runs after what | Drag from the square handle on a node's right to the one on another node's left |
| Dashed, round handle | Data dependency: where each input takes its value from | Drag from an output (circle on the right) to an input (circle on the left), or pick the source in the inspector |
The split is deliberate: order says when a node runs, dependencies say what it reads. A node can read the output of any node that ran before it on the same branch, not only its direct parent. In the inspector, the Data dependencies section lists what the node reads and who uses its outputs.
Input sources
Each node input has a source:
- Workflow input: a field declared on the Start node, asked when the run begins and read as
start.field. - Context: a path in the output of an earlier node, such as
jsonQuery.resultorhash.hex. The picker lists only the paths available at that point of the flow and disables incompatible types. - Ask during the run: the run pauses and asks for the value in a form.
- None: if the input is required it becomes an implicit runtime input: the editor warns and offers two shortcuts, make it a workflow input or mark it as "ask during the run".
Predictable context
While running, each node's outputs go into the context under the node id:
{
"start": { "document": "{\"user\":{\"email\":\"ana@example.com\"}}" },
"jsonQuery": { "result": "ana@example.com", "count": 1 },
"hash": { "hex": "5f2b…" }
}
Since branches cannot join yet, every node has at most one predecessor and the flow is a tree rooted at Start. So the context available at each node is exactly its ancestors' outputs, and the editor knows, before running, which paths exist at each point. A node on one Condition branch never sees what the other branch produced.
Not every output needs to reach the context. In the inspector, each output has Export to the context (on by default). A hidden output is not shown on the canvas or in the source picker, cannot be read by other nodes and is left out of the run log; the node shows how many outputs are hidden. Hiding an output someone reads asks first, and those inputs show an error until they get another source. Start and Ask input outputs are always exported.
Types
Inputs and outputs use structured types: string, number, boolean, any, enum, arrays (string[]) and objects with required or optional fields. They are checked twice:
- While editing: the source type must fit the input type. An
anyonly fits ananyinput; to read an inner field of a free-form output, declare its shape. - While running: every output is checked against its declared type. A value with the wrong shape stops the run with a clear error on the node.
JSON inputs (Format, Query, Validate schema, Flatten and JSON → YAML) take the document as JSON text or as a value another node already parsed, such as the value of Format. Text is always read as JSON.
Free-form outputs, such as a JSONPath result or the value converted from YAML, can have their shape declared in the inspector, typed by hand or inferred from a sample pasted as JSON.
Lists
The Lists nodes work on any list, and their output type follows the list bound to the input: a string[] in gives a string[] out; Pick field year over a list of { year, month } returns string[].
| Node | What it does |
|---|---|
| Remove duplicates | drops repeated items, by the whole item or by a field, keeping the first |
| Pick field | replaces each object with one of its fields |
| Filter list | keeps the items that match a rule (the Condition operators) |
| Sort list | sorts by value or by a field |
| Limit list | keeps the first or the last N |
| Join as text | joins the items with a separator |
Example: Regex: extract (all matches, matched text) → Remove duplicates → Join as text returns the unique emails of a text, one per line. Regex can also return only the first match, one capture group or the named groups as an object typed after the pattern.
Continuous validation
The workflow is revalidated on every edit. Issues show up on the node itself and in the Issues panel (clicking one selects the node), and they block the Run button while any error remains:
| Severity | Issue |
|---|---|
| Error | No Start node, or more than one |
| Error | Node with two incoming edges (joins are not supported yet) |
| Error | Loose node with no path from Start |
| Error | Unavailable context path (other branch, later node or missing path) |
| Error | Type mismatch between source and input |
| Error | Missing workflow input, removed node or invalid configuration |
| Warning | Required input without a source (asked during the run) |
| Warning | Condition branch with no node |
Running
- The tree is walked breadth first from Start. A Condition evaluates its rule and follows only the chosen branch; nodes on the other branch are marked skipped.
- Before each node, inputs that need a manual value pause the run and open the form. When you continue, it picks up where it stopped.
- Step through runs one node per click, handy for watching the context grow.
- The run panel shows the final result, every step with its inputs and outputs, and the accumulated context.
Save, export and import
- Automatic draft: the open workflow is stored on every edit, so reloading the page loses nothing.
- Saved: keep several named workflows and switch between them. Switching with pending changes asks for confirmation.
- Export / import: the JSON file (
format: "cicerotcv-workflow") can be versioned or shared. On import the format is validated and the workflow's issues show up before you run it.
Current limits
- No branch joins: every node has at most one predecessor.
- No HTTP request or code nodes yet.
- Nodes run in the browser, without network access.