run
run
Execute a named flow and return to the current flow when it completes. A run directive is the call-and-return mechanism for flow-to-flow control. Execution jumps to the named flow, runs all its steps, and then resumes from the statement after run in the calling flow. This is the primary way to organize multi-flow machines and to dispatch from decide branches.
When to use
Use run when you need to:
- Execute a named flow from within another flow and continue after it finishes
- Dispatch to different flows from
decidebranches - Organize a machine into reusable flow segments
- Call event handlers from
subscribes > ondeclarations
Use goto when you want to jump to a flow without returning (true tail-call). Use launch for async fire-and-forget execution of another machine. Use ask ... from to call another machine (not a flow within the same machine).
Syntax
run flow(<flow_name>)Or within event subscriptions:
subscribes on "<event>" run <flow_name>Examples
Simple flow dispatch
machine report_generator accepts report_type as text, is required data as map, is required
implements decide choose_report when input.report_type is "summary" run flow(generate_summary) when input.report_type is "detailed" run flow(generate_detailed) otherwise run flow(generate_default)
flows flow generate_summary compute build {report: "Summary: " + input.data.title, type: "summary"}
flow generate_detailed ask analyze, using: "anthropic:claude-sonnet-4-6" with task "Generate a detailed report from this data.\n\nData: ${JSON.stringify(input.data)}" returns report as text assuming report: "Detailed analysis..." compute build {report: steps.analyze.report, type: "detailed"}
flow generate_default compute build {report: "Default report for " + input.data.title, type: "default"}Call-and-return: continue after flow
machine pipeline implements compute setup {ready: true}
// run = call-and-return: execute process flow, then continue here run flow(process)
// This step executes AFTER the process flow completes compute finalize {done: true, processed: steps.setup.ready}
flows flow process compute work {result: "processed"}Event-driven flow dispatch
machine order_handler implements subscribes on "order.created" run validate_and_process on "order.cancelled" run handle_cancellation
flows flow validate_and_process ask validate, from: "@myorg/orders/validate" order_id: event.order_id returns valid as boolean assuming valid: true compute result {processed: steps.validate.valid}
flow handle_cancellation action refund call machine: "@myorg/billing/refund" order_id: event.order_id compute result {cancelled: true}Run vs goto
run flow(name) | goto flow(name) | |
|---|---|---|
| Behavior | Call-and-return | True tail-call |
| After execution | Returns to calling flow; remaining steps execute | Does not return; remaining steps are skipped |
| Stack | Adds to call stack | Does not add to stack (replaces) |
| Use case | Subroutines, modular flows | Self-loops, state machines, recursion |
Both are subject to flow depth protection (max 100 by default) to prevent infinite recursion.
Governance
run is a control-flow directive. It does not perform I/O and does not require governance approval. However, the steps inside the target flow inherit normal governance. If the target flow contains ask or action steps, those are governed individually.
The flow dispatch itself is recorded as a control-flow event in the behavioral ledger (Inv 5: Control-Flow Observability), including which flow was dispatched and from where.
Translations
| Language | Keyword |
|---|---|
| English | run |
| Spanish | ejecuta |
| French | execute |
| German | starte |
| Japanese | 実行 |
| Chinese | 运行 |
| Korean | 실행 |
See also
- decide - Branching logic, often uses
runin branches - launch - Async fire-and-forget (different machine)
- implements - The section where flows and run directives live
- goto - Tail-call variant (no return)