Variables
Variables are how data flows through your workflows. They allow nodes to pass information to each other, reference trigger data, and access environment configuration.
Variable Syntax
Use double curly braces to reference variables:
{{variable_name}}
{{node_name.output.field}}
{{trigger.body.message}}
Variable Sources
Trigger Variables
Data from the event that started the workflow:
{{trigger.body}} // Request body (webhooks)
{{trigger.headers}} // HTTP headers
{{trigger.params}} // URL parameters
{{trigger.query}} // Query string parameters
{{trigger.method}} // HTTP method
Node Output Variables
Results from previous nodes:
{{node_name.output}} // Complete output
{{node_name.output.field}} // Specific field
{{node_name.output.nested.field}} // Nested access
{{node_name.output[0]}} // Array index
{{node_name.output.items[0].name}} // Combined access
Environment Variables
Secure configuration values:
{{env.API_KEY}}
{{env.DATABASE_URL}}
{{env.SECRET_TOKEN}}
Loop Variables
Inside loop nodes:
{{loop.item}} // Current item
{{loop.index}} // Current index (0-based)
{{loop.length}} // Total items
{{loop.isFirst}} // Is first iteration
{{loop.isLast}} // Is last iteration
Parallel Variables
Inside parallel executions:
{{parallel.index}} // Parallel execution index
{{parallel.total}} // Total parallel executions
{{parallel.batchId}} // Current batch ID
Shared Memory
Workflow-level shared state:
{{shared.key}} // Access shared memory value
Expression Support
Variables support JavaScript expressions for dynamic values.
Logical Operators
{{value || "default"}} // OR with fallback
{{condition && "yes"}} // AND with value
{{!flag}} // NOT operator
Comparison Operators
{{count == 5}} // Equality
{{status != "error"}} // Inequality
{{total > 100}} // Greater than
{{price <= 50}} // Less than or equal
Ternary Operator
{{status == "active" ? "Yes" : "No"}}
{{items.length > 0 ? items[0] : null}}
Arithmetic
{{price * quantity}}
{{total + tax}}
{{(price * 1.1).toFixed(2)}}
String Operations
{{name.toUpperCase()}}
{{email.toLowerCase()}}
{{message.trim()}}
{{`Hello, ${name}!`}}
Array Operations
{{items.length}}
{{items.join(", ")}}
{{items.map(i => i.name)}}
{{items.filter(i => i.active)}}
{{items.find(i => i.id == targetId)}}
Object Operations
{{Object.keys(data)}}
{{Object.values(config)}}
{{JSON.stringify(result)}}
Resolution Hierarchy
When resolving a variable, FlowMaestro checks sources in this order:
- Node outputs — Results from workflow nodes
- Loop context — If inside a loop
- Parallel context — If in parallel execution
- Shared memory — Workflow-level storage
- Trigger data — Input that started the workflow
- Environment — Workspace environment variables
- Globals — System-level constants
Null and Undefined Handling
Handle missing values gracefully:
{{user.name || "Anonymous"}} // Default if null/undefined
{{user?.profile?.avatar}} // Optional chaining
{{data ?? "fallback"}} // Nullish coalescing
Type Coercion
Variables maintain their types through the workflow:
| Type | Examples |
|---|---|
| String | "hello", {{name}} |
| Number | 42, {{count}} |
| Boolean | true, {{isActive}} |
| Array | [1,2,3], {{items}} |
| Object | {key: "value"}, {{data}} |
| Null | null, {{missing}} |
Explicit Type Conversion
{{Number(stringValue)}} // To number
{{String(numericValue)}} // To string
{{Boolean(value)}} // To boolean
{{JSON.parse(jsonString)}} // Parse JSON
Common Patterns
Conditional Default Values
{{user.nickname || user.firstName || "User"}}
Safe Property Access
{{order?.customer?.email || "no-email"}}
Array Processing
// Get names from array of objects
{{users.map(u => u.name).join(", ")}}
// Filter and count
{{orders.filter(o => o.status == "pending").length}}
// Find specific item
{{products.find(p => p.sku == targetSku)}}
Template Strings
{{`Order #${order.id} for ${customer.name}`}}
{{`Total: $${(price * quantity).toFixed(2)}`}}
Date Formatting
{{new Date().toISOString()}}
{{new Date(timestamp).toLocaleDateString()}}
Using Variables in Nodes
In Text Fields
Simply insert the variable:
Hello, {{user.name}}! Your order #{{order.id}} is ready.
In JSON Fields
Use within JSON structures:
{
"to": "{{customer.email}}",
"subject": "Order {{order.id}} Confirmed",
"body": "{{email_body}}"
}
In Code Nodes
Access via the inputs object:
const userName = inputs.user.name;
const orderTotal = inputs.order.total;
return {
greeting: `Hello, ${userName}!`,
formattedTotal: `$${orderTotal.toFixed(2)}`
};
Variable Explorer
Use the Variable Explorer to browse available variables:
- Click in any variable field
- Press Cmd/Ctrl + Space
- Browse and select from available variables
Debugging Variables
Preview Values
In the workflow editor, hover over a variable to see its current value in test mode.
Execution Logs
View resolved variables in execution details:
{
"nodeId": "llm_1",
"resolvedInputs": {
"prompt": "Summarize this: Lorem ipsum...",
"temperature": 0.7
}
}
Best Practices
Use Descriptive Names
// Good
outputVariable: "customer_order_details";
// Avoid
outputVariable: "data";
Handle Missing Data
// Always provide fallbacks for optional data
{{user.preferences?.theme || "light"}}
Keep Expressions Simple
// For complex logic, use a Transform node instead of inline expressions
Validate Before Use
Use conditional nodes to check for required data before processing.
Document Variables
Add descriptions to output variables:
{
outputVariable: "processed_results",
description: "Array of validated customer records"
}