Reference
StepFlow
Context & Variables

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: $firstResultctx.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

Fieldparameterssetoutputcatch
input
$vars
context
result
errorOutput