Skip to main content

SubFlow

Use the SubFlow trigger when you want a flow that other flows can call as a step — like a function. SubFlows are reusable building blocks: you define common logic once (e.g. "normalize customer number", "validate address", "send compliance notification") and any other flow can invoke it inline with typed inputs and outputs.

A SubFlow doesn't run on its own. There is no schedule, no record event, no webhook — the only way it ever executes is when another flow's Run SubFlow step calls it.

What happens when the flow runs

  1. A calling flow's Run-SubFlow step evaluates its configured input bindings (constants, variable references, SmartField expressions) and hands the values to the SubFlow.
  2. AutoFlow looks up the SubFlow's pinned published version, projects the inputs into the SubFlow body as if they were trigger outputs, and starts dispatching steps.
  3. Steps inside the SubFlow run in the same transaction as the calling flow — no commit boundary between them. Anything the SubFlow writes is visible to the caller's later steps; if either side errors, the whole call rolls back as one unit.
  4. The SubFlow ends with a Return SubFlow Output step, which packages typed output values and hands them back to the Run-SubFlow caller.
  5. The calling flow continues with the SubFlow's outputs available as variables on the Run-SubFlow step.
caution

Time-based deferral steps (Sleep, polling) are not allowed inside a SubFlow. The caller is waiting synchronously; pausing in the middle would stall it. Use deferral only in the calling flow, before or after the Run-SubFlow step.

Configuration

FieldRequiredWhat it does
SubFlow descriptionYesShown in the picker when this SubFlow is added as a step in another flow. Pick a verb-phrase that describes what callers get (e.g. "Normalize customer number", not "CustNo trigger").
Input ParametersNoEach row declares a parameter callers must (or may) bind a value to.

Input parameters

Each input parameter has:

  • Name — letters, digits, and underscore only. No spaces. The calling flow sees this name when it binds the value.
  • TypeValue or Reference. Value parameters take any literal, variable, or SmartField/SmartFormula expression at the call site (numbers and dates are passed as text on the wire). Reference parameters take a SmartField record reference; if a Table No. is set on the row, the calling flow's selector is narrowed to records of that table, otherwise any record is accepted.
  • Required — when set, callers must bind a value. When cleared, an unbound parameter defaults to empty.

A SubFlow with zero input parameters is fine — it's the right shape for a SubFlow that reads BC state directly without caller-supplied values (e.g. "Send daily summary email").

Recursion and depth

A SubFlow may call other SubFlows, and even (directly or indirectly) call itself. Runtime recursion is allowed; static cycle detection at publish time is deliberately not done — it's brittle and would block legitimate use cases like SubFlow-based tree traversal.

Endless recursion is bounded by a single per-execution depth counter capped at 32 by default. The cap is configurable in AutoFlow Setup → SubFlows → Maximum SubFlow nesting depth. Crossing the cap fails the calling step with a clear error that names the call chain.

Errors propagate

If the SubFlow hits an Error step (or any step throws), the failure is wrapped and returned to the calling Run-SubFlow step as:

Error in SubFlow "<name>": <original message>

The whole transaction rolls back, including anything the SubFlow wrote, so partial state can never leak. This makes Error step inside a SubFlow the idiomatic way to reject an invalid call (more natural than emitting a "validate=false" output and asking the caller to check it).

Logging

The SubFlow has no separate execution log. Its inner steps appear nested under the calling Run-SubFlow step in the parent flow's Execution Log, so the whole call tree is readable in one place.

Block colour at a glance

In the editor, the SubFlow trigger uses the regular yellow trigger palette — it's a trigger like any other. The Run-SubFlow step at the call site uses a green palette and the same subtask icon glyph (in the green stroke variant) so you can spot at a glance where another flow is composing this SubFlow's logic.

Returning output to the caller

Every SubFlow ends with a Return SubFlow Output step, available from the Essentials palette. It packages typed output values, hands them back to the calling Run-SubFlow step, and ends the SubFlow's execution.

It is a terminating step – any step placed after it is a publish-time error.

A SubFlow that returns nothing — no output parameters declared — is fine. The calling Run-SubFlow step simply has no outputs to project.

What happens when Return SubFlow Output runs

  1. The runner evaluates each output parameter's Value expression in the SubFlow's context (variables, SmartFields, formulas).
  2. The values are signalled to the calling Run-SubFlow step as named outputs, typed Value or Reference per the parameter declaration.
  3. The SubFlow's execution ends. Control returns to the caller, which continues with the outputs available as variables on the Run-SubFlow step.

If the SubFlow errors before reaching its Return Output step, no outputs are returned — the error propagates to the calling Run-SubFlow step instead, and the entire shared transaction rolls back. Output values you would have returned are simply not produced. This is the right shape for SubFlows that do validation: an Error step rejects the call cleanly, and the caller decides how to react (retry, log, etc.).

Configure the Return SubFlow Output step

Add Return SubFlow Output to the flow and fill in the configuration card.

Description

Block label in the editor.

Output parameters

One row per value to return. Each row has Name, Type, and a Value expression.

  • Name – the name the calling flow will see on the Run-SubFlow step's outputs. Match it to whatever the caller will reference (e.g. NormalizedNo, IsValid, Total).
  • TypeValue or Reference. Value outputs surface on the calling step as a plain text variable; the caller can use it directly in expressions or re-parse it as needed. Reference outputs (with an optional Table No. narrowing) surface as a record reference the caller can bind into a record-scoped SmartField. The value travels as text on the wire either way; the type tells the calling step's SmartField selector what to expect.
  • Value – an expression (variable reference, SmartField, formula) producing the output. The engine substitutes references just before the step runs.