- Get started
- Build
- The canvas
- Variables and data flow
- Expression syntax
- Control flow
- Error handling
- Output mocking
- Evaluations
- Deploy and run
- Examples
- Reference
Variables and data flow
How data flows between nodes through node output and variables, with scoping rules for subflows and branches.
Nodes in a workflow do not share data automatically. When a node produces output, such as an HTTP response or a computed value, the nodes after it, called downstream nodes, read that output through expressions. An expression is a short piece of JavaScript that reads or computes a value. Data flow is how a workflow passes values between nodes and keeps them for the length of a run.
Data moves through a workflow in two ways:
- Node output: each node produces output that downstream nodes can reference.
- Variables: workflow-level values that you define to store and pass values between nodes.
Expression syntax describes the full grammar, the operators, and how to write $vars references.
How it works
Node output
Every node that produces data makes it available through $vars.<nodeName>.output. The node name is assigned automatically from the node type. For example, the first HTTP Request node is named httpRequest1, and the second is named httpRequest2.
A node's variable name is its ID, shown on the Advanced tab of the properties panel when the node is selected. The pencil icon next to ID changes it.
// Access HTTP Request response
$vars.httpRequest1.output.body
$vars.httpRequest1.output.code
// Access Script return value
$vars.script1.output
// Access a second HTTP Request
$vars.httpRequest2.output.body
// Access HTTP Request response
$vars.httpRequest1.output.body
$vars.httpRequest1.output.code
// Access Script return value
$vars.script1.output
// Access a second HTTP Request
$vars.httpRequest2.output.body
The output structure depends on the node type. Each page of the node reference lists the output of its node.
Node errors
When a node fails and its error handle is connected, the details of the failure are on $vars.<nodeName>.error, next to the node's output. Read them in the nodes on the error path, for example in a Script node that logs the failure:
// Read the error of a failed HTTP Request
$vars.httpRequest1.error.message // what went wrong
$vars.httpRequest1.error.status // the HTTP status, for example 404
// Read the error of a failed HTTP Request
$vars.httpRequest1.error.message // what went wrong
$vars.httpRequest1.error.status // the HTTP status, for example 404
The error object exists only on the error path. On the success path, $vars.<nodeName>.error is undefined. The error object lists all its fields.
Variables
Variables are workflow-level values that persist for the duration of a single run. You define them in the Variables panel, which opens from the Variables tab next to the Properties tab on the right. The panel lists the Inputs, Outputs, and Variables of the workflow, and the output of each node. A toggle switches between All variables and Selected node. The Focus on node icon on a node's row zooms the canvas to that node. With Selected node on, the panel is limited to the selected node, and its header shows the name of that scope, for example Scope: Manual trigger.
The + next to Variables in the panel opens the Add variable dialog. Each variable has:
- Name: how you reference it in expressions, for example
$vars.orderTotal. - Data type: String, Number, Boolean, Object, or Array.
- Description: an optional note on what the value represents.
- Default value: an optional starting value.
Workflow-level variables are always bidirectional: any node can read or write them. There is no direction setting to configure. A read-only or write-only value comes from a trigger input or an output variable instead, described below.
The three kinds of data differ by where you define them:
| Kind | Defined in | Direction | Reference syntax |
|---|---|---|---|
| Variable | Variables panel, next to Variables | Bidirectional (read and write) | $vars.<name> |
| Trigger input | On the trigger node, or in the Variables panel next to the trigger | Read-only | $vars.<triggerName>.output.<name> |
| Output variable | On an End node, or in the Variables panel next to Outputs | Write-only | $vars.<name> |
When to use each:
- Node output fits data that passes from one node to the next. This is the most common pattern.
- Variables fit values that must be accessible across the entire workflow.
- Inputs and outputs fit values that define what the workflow itself receives or returns, as described in Trigger inputs and Output variables below.
Descriptive camelCase names, such as customerEmail, invoiceTotal, and apiResponse, remain readable in execution traces over time. Single-letter names and abbreviations lose meaning quickly.
Trigger inputs
Input variables are not defined in the Variables section. They are added as input arguments in the trigger's properties panel, or with the + next to the trigger in the Variables panel, which opens the Add input variable dialog. Both ways make them read-only. When a trigger fires, its inputs are available as $vars.<triggerName>.output.<inputName>:
// Access an input defined on a Manual Trigger named "manualTrigger1"
$vars.manualTrigger1.output.userId
// Access an input defined on a Manual Trigger named "manualTrigger1"
$vars.manualTrigger1.output.userId
This applies to all trigger types. If your workflow has multiple triggers, each trigger owns its own inputs, and downstream nodes reference the specific trigger that started the run.
Output variables
Output variables represent the result of the workflow. They are added with Add output variable on the Parameters tab of an End node, or with the + next to Outputs in the Variables panel. They are write-only.
// Access an output variable named "finalStatus"
$vars.finalStatus
// Access an output variable named "finalStatus"
$vars.finalStatus
Each output variable has:
- Name: how you reference it in expressions, for example
$vars.finalStatus. - Data type: String, Number, Boolean, Object, or Array.
- Description: an optional note on what the value represents.
- Default value: an optional fallback used when nothing sets the variable.
An output variable's value is set the same way as any other variable: from a node's Update Variable section, or as a Script node's return value.
Variable definitions
Variable definitions live in the Variables panel. Each definition stores the variable name and type so the value can be referenced consistently during a run.
Variable updates
Variables can be updated by node configuration or by Script node output.
From any node
Every node has an Update Variable section on the Advanced tab of the properties panel, where Add variable update adds an assignment. The section stores a writable variable target, which is a workflow variable or an output variable, and the JavaScript expression assigned to it. The expression is evaluated after the node completes.
From a Script node
A Script node's return value is accessible downstream as $vars.<scriptName>.output. The Script node also has the same Update Variable section as other nodes for direct variable writes:
// The return value becomes $vars.script1.output
return {
orderTotal: $vars.httpRequest1.output.body.price * $vars.httpRequest1.output.body.quantity
};
// The return value becomes $vars.script1.output
return {
orderTotal: $vars.httpRequest1.output.body.price * $vars.httpRequest1.output.body.quantity
};
Scoping rules
A node can access output from:
- Upstream nodes in the same scope: nodes at the same level that executed before it.
- Parent container nodes: if the node is inside a subflow or loop, it can access the parent's scope.
Scope means the part of a workflow where a name can be read. A node cannot access output from:
- Nodes in a different branch: if a Decision or Switch sent the run down a different path, those nodes' output is not available.
- Nodes that have not executed: output only exists after a node runs.
Subflow scoping
Subflows create their own variable scope. Nodes inside a subflow can access:
- Other nodes within the same subflow
- The parent workflow's scope
Variables updated inside a subflow are namespaced, which means prefixed with the subflow name, to avoid collisions with the parent workflow. For example, a variable counter inside a subflow named subflow1 is referenced as $vars.subflow1.counter from outside the subflow.
The subflow's return value is accessible to the parent workflow as $vars.<subflowName>.output.
Parallel branches
Each parallel branch has its own variables. Mutating a variable inside one branch does not make that change visible in another branch. A Merge node consolidates outputs from parallel paths when the paths need to rejoin.
Patterns
Building dynamic strings
Template literals in a Script node combine variables and static text:
return `Hello ${$vars.firstName}, your order #${$vars.orderId} has shipped.`;
return `Hello ${$vars.firstName}, your order #${$vars.orderId} has shipped.`;
Accumulating values in a loop
An accumulator pattern uses an array initialized before the Loop node and appended to inside the loop body:
// Script node inside the Loop body
results.push(item.processedValue);
return results;
// Script node inside the Loop body
results.push(item.processedValue);
return results;
Keeping secret values out of logs
Secret variable values are masked in the UI but may appear in exported trace data. Logging them is a data exposure risk.
Practical example
A workflow that fetches a user from an API and routes based on their role has three nodes:
- HTTP Request (
httpRequest1): sends a GET request tohttps://api.example.com/users/42. - Script (
script1): extracts the user's role, with this code:
const user = $vars.httpRequest1.output.body;
return {
name: user.name,
role: user.role,
isAdmin: user.role === "admin"
};
const user = $vars.httpRequest1.output.body;
return {
name: user.name,
role: user.role,
isAdmin: user.role === "admin"
};
- Decision (
decision1): branches on admin status, with this expression:
$vars.script1.output.isAdmin === true
$vars.script1.output.isAdmin === true
The True branch grants admin access, and the False branch grants standard access.
Next steps
- Expression syntax:
$varsgrammar, operators, where expressions are written, and common errors. - Script node: writing JavaScript, return values, and
$varsaccess. - Decision node: branching on expressions.
- The Flow canvas: the properties panel and the Variables panel.
- Community: ask questions and share workflows with other builders on the UiPath Forum.
- How it works
- Node output
- Node errors
- Variables
- Trigger inputs
- Output variables
- Variable definitions
- Variable updates
- From any node
- From a Script node
- Scoping rules
- Subflow scoping
- Parallel branches
- Patterns
- Building dynamic strings
- Accumulating values in a loop
- Keeping secret values out of logs
- Practical example
- Next steps