Step Functions - Graph not rendering properly in Parallel state
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 810
- Avg merge
- 10h 12m
- Merged PRs (30d)
- 7
Description
## Problem
When rendering a definition with certain step types the steps order becomes relevant and the resulting graph becomes incorrect.
This is a bug when rendering the graph. It not only happens on vs code but also on the **Graph view of the AWS console**.
## Steps to reproduce the issue
You can reproduce it parting from the given definition.
```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
}
}
}
]
}
}
}
```
For that given definition the resulting graph is the following:

Until here everything is fine 👍
The problem arise when you're using a tool on top of ASL that moves step ordering.
For instance, here's what happens for almost the same definition. Just moving the `FIRST_STEP_HERE` down one position.
```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
}
}
}
]
}
}
}
```
As you can see in the graph below ⬇️ Now it's totally incorrect and apparently nothing calls the `FIRST_STEP_HERE` ❓

Now, if you want to broke the graph just do some more ordering changes:
```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
}
}
}
]
}
}
}
```

## Expected behavior
So, given the [language specification](https://states-language.net/spec.html) and as far as I understand ordering shouldn’t be a factor to determine state machine functionality and in fact, if you test this flow, it works as expected so there's a mismatch between the logic and the rendering.
I must also mention that there's a weird combination of step types what produce this error. If you play with the provided definition you may notice that if you remove the `Choice` or the `Done` step, or just if you get the code out of the parallel state everything works fine. I think even if you remove the `BeforeDoOperation` step everything works just perfectly.
## System details (run the `AWS: About Toolkit` command)
- OS: MacOS 12.3.1
- Visual Studio Code version: 1.67.2
- AWS Toolkit version: v1.38.0
Contributor guide
Research direction
Reproduce the issue in the VS Code AWS Toolkit Graph view using the provided Parallel state definitions, changing only the order of States entries. Trace the graph-rendering path responsible for Parallel states and Choice/Pass/Fail combinations; done means equivalent definitions render the same graph regardless of state ordering, with coverage for the supplied cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript, vscode
- Domain
- devtools, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100