Skip to content

bug: Callback pattern doesn't work correctly #12642

@alisherzhaken

Description

@alisherzhaken

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I implemented two state machines where one state machine (parent) invokes another state machine (child), and I have utilised a callback pattern where Child State Machine will perform sendTaskHeartbeat every 30 seconds. Parent State Machine has a heartbeat timeout of 40 seconds.

The problem lies in sendTaskHeartbeat. It seems like the callback doesn't make it to the parent state machine, which causes the Parent Task to time out after 40 seconds, and the sendTaskHeartbeat step in Child State Machine fails with Sfn.InvalidTokenException.

Here are the definitions.

# Parent state machine

{
  "StartAt": "StartChild",
  "States": {
    "StartChild": {
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync:2",
      "HeartbeatSeconds": 40,
      "Arguments": {
        "Input": {
          "TaskToken": "{% $states.context.Task.Token %}",
          "count": 0
        },
        "StateMachineArn": "arn:aws:states:us-east-1:000000000000:stateMachine:ChildStateMachine"
      },
      "End": true
    }
  },
  "QueryLanguage": "JSONata"
}

and

# Child State Machine

{
  "StartAt": "Heartbeat",
  "States": {
    "Heartbeat": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:sfn:sendTaskHeartbeat",
      "Arguments": {
        "TaskToken": "{% $states.context.Execution.Input.TaskToken %}"
      },
      "Output": "{% $states.input %}",
      "Next": "IncrementPoint"
    },
    "IncrementPoint": {
      "Type": "Pass",
      "Output": {
        "count": "{% $states.input.count + 1 %}"
      },
      "Next": "Delay"
    },
    "Delay": {
      "Type": "Wait",
      "Seconds": 10,
      "Next": "CheckEnd"
    },
    "CheckEnd": {
      "Type": "Choice",
      "Choices": [
        {
          "Condition": "{% $states.input.count = 3 or $states.input.count = 6 or $states.input.count = 9%}",
          "Next": "Heartbeat"
        },
        {
          "Condition": "{% $states.input.count < 10 %}",
          "Next": "IncrementPoint"
        }
      ],
      "Default": "Finish"
    },
    "Finish": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:sfn:sendTaskSuccess",
      "Arguments": {
        "TaskToken": "{% $states.context.Execution.Input.TaskToken %}",
        "Output": "{% $states.input %}"
      },
      "End": true
    }
  },
  "QueryLanguage": "JSONata"
}

Expected Behavior

It is expected to see sendTaskHeartbeat to be successful such that the execution of both Parent and Child State Machine would continue and end up successful instead of timing out.

How are you starting LocalStack?

Using localstack start

Steps To Reproduce

How are you starting localstack (e.g., bin/localstack command, arguments, or docker-compose.yml)

localstack start

Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

awslocal 
awslocal iam create-role --role-name AllPurpose --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "states.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}'

awslocal iam create-policy --policy-name AllPurpose \
--policy-document '{
     "Version": "2012-10-17",
     "Statement": [
          {
             "Action": "*",
             "Resource": "*",
             "Effect": "Allow"
          }
      ]
   }'

awslocal iam attach-role-policy --role-name AllPurpose --policy-arn arn:aws:iam::000000000000:policy/AllPurpose

awslocal stepfunctions create-state-machine --definition file://parent-state-machine.json --role-arn arn:aws:iam::000000000000:role/AllPurpose --name ParentStateMachine

awslocal stepfunctions create-state-machine --definition file://child-state-machine.json --role-arn arn:aws:iam::000000000000:role/AllPurpose --name ChildStateMachine

awslocal stepfunctions start-execution --state-machine-arn arn:aws:states:us-east-1:000000000000:stateMachine:ParentStateMachine

Environment

- OS: Ubuntu 25.04
- LocalStack:
  LocalStack version: 4.4.0
  LocalStack Docker image sha:
  LocalStack build date: 2025-05-08
  LocalStack build git hash: 21f6e5fb2

Anything else?

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions