- Get started
- Build
- Deploy and run
- Examples
- Reference
Subflow
Group nodes into a subflow that runs as one step inside a workflow, pass data in and out of it, and scope its variables.
A subflow is a workflow embedded within another workflow, called the parent workflow. It groups a set of nodes into a self-contained unit that runs as part of the parent and returns output to it. Subflows organize complex logic into self-contained, manageable groups.
How it works
When a parent workflow reaches a subflow node, the run enters the subflow and runs its nodes in sequence. The subflow has its own scope, the part of a workflow where a name can be read, so variables defined inside it do not collide with variables in the parent workflow. When the subflow completes, its output is passed back to the parent workflow and the run continues with the next node.
Nodes inside a subflow can access:
- Other nodes within the same subflow.
- The scope of the parent workflow.
The subflow's output is accessible to the parent workflow as $vars.<subflowName>.output.
Adding a subflow
A Subflow node is added from the Add node panel, where it is listed in the Maestro Flow category, and it connects to the node before it. It appears on the canvas as a node with a stacked-layers icon. The Drill into button on the node's hover toolbar opens the inside of the subflow as its own canvas. A breadcrumb at the top left, with a home icon and the subflow name, leads back to the parent workflow. The inside starts with a Start node connected to an End node, and it has the same bottom toolbar as the main canvas, so nodes are added in the same way.
Passing data in and out
Inputs
The Inputs section of the subflow node's properties panel defines the input variables of the subflow and maps expressions from the parent scope to them. Add input variable adds an input. Each input has a name, a type, and a Value, an expression that is evaluated in the parent workflow's scope. The Insert menu of the Value field lists the values of that scope, such as the nodes before the subflow and $metadata.
Inside the subflow, the inputs are outputs of the subflow's Start node. The Insert menu lists that node as <subflowName>Start, for example $vars.subflow1Start.output.orderData. The Start node also offers Add input argument.
Output
The Outputs section of the subflow node defines the output variables of the subflow. Add output variable adds one, and the values are mapped through the output mappings of the End node inside the subflow. The output is available to the parent workflow as $vars.<subflowName>.output, and each output variable is a field of it, for example $vars.subflow1.output.isValid. Any node after the subflow can reference it in an expression, as with any other node output.
// Access the output of a subflow named "validateOrder"
$vars.validateOrder.output
$vars.validateOrder.output.isValid
// Access the output of a subflow named "validateOrder"
$vars.validateOrder.output
$vars.validateOrder.output.isValid
Variable scoping
Subflows create their own variable scope. Variables updated inside a subflow are namespaced, which means prefixed with the subflow name, to avoid collisions with the parent workflow.
From outside the subflow, a subflow's internal variables are referenced as $vars.<subflowName>.<variableName>. For example, a variable counter inside a subflow named subflow1 is referenced as $vars.subflow1.counter from the parent workflow.
From inside the subflow, nodes access their sibling nodes' output using the standard $vars.<nodeName>.<property> pattern. They can also read from the parent workflow's scope directly.
Variable namespacing prevents a subflow's internal variables from overwriting parent variables that share the same name. Variable names do not need to be coordinated between the parent and the subflow.
Practical example
A parent workflow calls a subflow to validate order data before processing it.
The parent workflow has three nodes:
- HTTP Request (
httpRequest1): fetches order data from an external API. - Subflow (
validateOrder): validates the order data and returns a result. - Decision (
decision1): branches based on the validation result.
The validateOrder subflow has one node, Script (script1), which checks that the required fields are present and that the order total is above zero:
const order = $vars.validateOrderStart.output.orderData;
const isValid = order.items.length > 0
&& order.total > 0
&& order.customerId !== undefined;
return { isValid: isValid, reason: isValid ? "OK" : "Missing required fields" };
const order = $vars.validateOrderStart.output.orderData;
const isValid = order.items.length > 0
&& order.total > 0
&& order.customerId !== undefined;
return { isValid: isValid, reason: isValid ? "OK" : "Missing required fields" };
The Outputs section of the subflow node defines an output variable named isValid with the Boolean data type, and the End node inside the subflow maps it to $vars.script1.output.isValid. Back in the parent workflow, the Decision node evaluates $vars.validateOrder.output.isValid === true and routes to either a fulfillment path or an error-handling path.
Next steps
- Variables and data flow: variable scoping rules, expression syntax, and
$varsaccess patterns. - The Flow canvas: the canvas, the properties panel, and the Add node panel.
- Error handling: configuring error handles on nodes, including inside subflows.
- Community: ask questions and share workflows with other builders on the UiPath Forum.