Context & Variables
Understanding the execution context and workflow variables in StepFlow.
WorkflowContextView
JSONata expressions execute against WorkflowContextView:
{
"input": {
// Current step's input data
// First step: workflow's initial input
// Subsequent steps: previous step's output
},
"vars": {
// Workflow variables set via `set`
"userId": 42,
"orderData": { ... }
},
"global": {
// Global workflow configuration
},
"context": {
"execution": {
"id": "exec-abc123",
"startTime": "2024-01-15T10:00:00Z"
},
"step": {
"name": "ProcessOrder",
"type": "task"
},
"workflow": {
"id": "wf-xyz",
"name": "order-processing"
},
"task": {
"token": "..." // For callback mode
},
"map": {
"item": {
"index": 0,
"value": { ... }
}
}
},
"result": {
// Step execution result (output mapping only)
},
"error_output": {
// Error details (catch context only)
"error": "ServiceError",
"cause": "Connection timeout",
"timestamp": "..."
}
}Variable Naming Rules
Workflow Variables
Set via DSL set field, access with $ prefix:
// Setting
"set": { "firstResult": "{% $ %}" }
// Accessing
"{% $firstResult.input.value %}"Internal mapping: $firstResult → ctx.vars["firstResult"]
Reserved Prefixes
$steps.*— Built-in aliases (deprecated, use direct access)$count(),$sum(), etc. — JSONata functions
Validation
Unknown $name references will error:
Unknown workflow variable '$foo'.
Workflow variables must be set via 'set' in a previous step
and referenced as '$foo'.Data Flow Between Steps
Step 1: Initial Input
{
"entry": "StepA",
"steps": {
"StepA": {
"type": "task",
"parameters": {
"id": "{% input.orderId %}" // input = workflow input
},
"set": {
"orderData": "{% result %}"
},
"output": {
"order": "{% result.order %}"
},
"next": "StepB"
}
}
}Step 2: Receives Previous Output
{
"StepB": {
"type": "task",
"parameters": {
"order": "{% input.order %}", // input = StepA's output
"fullData": "{% $orderData %}" // $vars persists
}
}
}Context Fields
context.execution
Execution instance metadata:
{
"parameters": {
"traceId": "{% context.execution.id %}",
"startedAt": "{% context.execution.startTime %}"
}
}context.step
Current step info:
{
"parameters": {
"currentStep": "{% context.step.name %}"
}
}context.map.item
Available inside Map's itemProcessor:
{
"parameters": {
"itemIndex": "{% context.map.item.index %}",
"itemValue": "{% context.map.item.value %}"
}
}Best Practices
1. Use input and $vars as Primary Sources
// ✅ Recommended
{
"parameters": {
"userId": "{% input.userId %}",
"config": "{% $globalConfig %}"
}
}
// ❌ Avoid
{
"parameters": {
"userId": "{% context.someBusinessData %}"
}
}2. Flatten Data with set
{
"set": {
"userId": "{% result.user.id %}",
"userName": "{% result.user.name %}"
}
}
// Later steps use flat variables
{
"parameters": {
"id": "{% $userId %}",
"name": "{% $userName %}"
}
}3. Pre-set Variables Before Map
{
"PrepareData": {
"type": "set",
"set": {
"requestId": "{% input.requestId %}",
"userId": "{% input.userId %}"
},
"output": {
"items": "{% input.items %}"
},
"next": "ProcessItems"
},
"ProcessItems": {
"type": "map",
"items": "{% input.items %}",
"itemProcessor": {
"entry": "Process",
"steps": {
"Process": {
"type": "task",
"parameters": {
"itemId": "{% input.id %}", // From item
"userId": "{% $userId %}", // From vars
"requestId": "{% $requestId %}" // From vars
}
}
}
}
}
}Availability Summary
| Field | parameters | set | output | catch |
|---|---|---|---|---|
input | ✅ | ✅ | ✅ | ✅ |
$vars | ✅ | ✅ | ✅ | ✅ |
context | ✅ | ✅ | ✅ | ✅ |
result | ❌ | ✅ | ✅ | ❌ |
errorOutput | ❌ | ❌ | ❌ | ✅ |