States in a CloudFlow workflow act like functions: each state receives input, processes it, produces output, and stores the output in the context. The runtime data available to each state is called the context.
How data flows between states
A CloudFlow workflow passes data through a chain of states. At each step:
The current state receives input from the previous state (or from the execution input, for the first state).
The state processes the input according to its type and configuration.
The state produces output and passes it to the next state.
You can customize how data enters and leaves each state by defining an InputConstructor or OutputConstructor. Without these constructors, each state type applies its own default behavior. See Inputs and outputs for details.
Two categories of data are available at runtime:
| Category | Contents |
|---|---|
| Flow data | Flow name, region, state names, and the Resource Access Management (RAM) role used to run the flow |
| Execution data | Execution name and input, the current state's input and output, the callback token, error details, and the retry count |
Access runtime data with $Context
Use the $Context expression to read flow and execution data from any state. The full context structure:
{
"Execution": {
"Name": "String",
"Input": {},
"RoleArn": "String"
},
"Current": {
"Name": "String",
"Input": {},
"Output": {},
"Error": {
"Code": "String",
"Detail": "String"
},
"RetryCount": "Number",
"TaskToken": "String"
}
}| Field | Type | Description |
|---|---|---|
Execution.Name | String | Unique name of the current execution |
Execution.Input | Object | Input provided when the execution started |
Execution.RoleArn | String | ARN of the RAM role used to run the flow |
Current.Name | String | Name of the current state |
Current.Input | Object | Input received by the current state |
Current.Output | Object | Output produced by the current state |
Current.Error.Code | String | Error code, if the state encountered an error |
Current.Error.Detail | String | Error detail message |
Current.RetryCount | Number | Number of retries performed for error handling |
Current.TaskToken | String | Token for asynchronous task callbacks |
Where to use $Context
| Use case | Example |
|---|---|
| Input and output constructors | See Inputs and outputs |
| ItemsPath in Map states | $Context.Current.Input |
| Condition in Choice states | $Context.Current.Input.Size>=1024 |
| Error handling | $Context.Current.Error.Code, $Context.Current.Error.Detail |
| Task callback tokens | $Context.Current.TaskToken |
Shortcuts: $Input and $Output
CloudFlow provides two shortcuts for the most frequently accessed paths:
| Shortcut | Equivalent | Use when |
|---|---|---|
$Input | $Context.Current.Input | Reading the data a state received |
$Output | $Context.Current.Output | Reading the data a state produced |
Note:$Inputand$Outputrefer to the current state only. To access the original execution input from any state, use$Context.Execution.Input.
Default input/output behavior by state type
Without an InputConstructor or OutputConstructor, each state type handles data as follows:
| State type | Default input | Default output |
|---|---|---|
| Pass, Succeed, Fail, Wait | Receives input from the previous state | Passes the input through as output, unchanged |
| Choice | Receives input from the previous state | Forwards the input to the matching branch (or the Default branch). Does not produce output of its own |
| Parallel | Deep-copies the input and sends a copy to each branch simultaneously | A Map[String]Any where keys are implicit branch names (Branch N) and values are the branch results |
| Map | Iterates over the input array (or, if the input is a Map[String]Any and no ItemsPath is specified, iterates over its values) | A Map[String]Any where the key is Items and the value is an array of iteration results |
| Task | Receives input from the previous state or an external source | The task execution result, after running business logic and using $Context to access and manipulate data |
Example: trace data through a Parallel state
This example shows how InputConstructor shapes data in a Parallel state and how the context looks at each step of execution.
Flow definition
Type: StateMachine
Name: DataTransferExample
SpecVersion: v1
StartAt: Step1
States:
- Type: Pass
Name: Step1
Next: Step2
- Type: Parallel
Name: Step2
InputConstructor:
FieldA: 123
Branches:
- StartAt: Pass1
States:
- Type: Pass
Name: Pass1
End: true
- StartAt: Pass2
States:
- Type: Pass
Name: Pass2
End: true
Next: Step3
- Type: Pass
Name: Step3
End: trueData at each step
The following trace shows the data as it moves through the workflow. Assume the execution starts with an empty input {}.
Step 1 -- Step1 (Pass)
| Field | Value | Reason |
|---|---|---|
Current.Input | {} | Receives the execution input directly |
Current.Output | {} | Pass states forward input unchanged |
Step1 passes {} to Step2.
Step 2 -- Step2 (Parallel) with InputConstructor
| Field | Value | Reason |
|---|---|---|
| Input from Step1 | {} | Output of the previous state |
| After InputConstructor | {"FieldA": 123} | InputConstructor replaces the original input with a new JSON object |
The constructed object {"FieldA": 123} is deep-copied and sent to both branches simultaneously.
Step 3 -- Pass1 and Pass2 (inside Parallel branches)
Each branch receives {"FieldA": 123} as input. Both are Pass states, so each forwards its input unchanged as output.
The context inside Pass1 at runtime:
{
"Execution": {
"Name": "xxxx-xxxx-xxxx-xxxx",
"Input": {},
"RoleArn": "xxxx"
},
"Current": {
"Name": "Pass1",
"Input": {
"FieldA": 123
},
"Output": {
"FieldA": 123
},
"Error": null,
"RetryCount": 0
}
}Observations:
Current.InputandCurrent.Outputboth contain{"FieldA": 123}because Pass states forward input as output.Execution.Inputremains{}(the original execution input), unaffected by InputConstructor.ErrorisnullandRetryCountis0because no errors occurred.
Step 4 -- Step2 collects results, Step3 (Pass) receives them
Step2 collects branch outputs into a Map[String]Any result. Each branch result uses an implicit name (Branch N) as its map entry. Step3 receives this combined result and forwards it unchanged.