question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[aws-stepfunctions-tasks] StepFunctionsStartExecution should receive a JSON Path at name instead a fixed string

See original GitHub issue

When the aws-stepfunctions-tasks.StepFunctionsStartExecutionProps.name is assigned and I execute more than one NestedStateMachine, the second State Machine It try to execute fails because a State Machine with the same name already exist.

The aws-stepfunctions-tasks.StepFunctionsStartExecution receives the name parameter. With this name the class generates the following result:

"ExampleState": {
      "Next": "NextState",
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync:2",
      "Parameters": {
        "Input.$": "$$.Execution.Input",
        "StateMachineArn": "arn:aws:states:us-east-1:123456:stateMachine:XYZ",
        "Name": "ExampleName"
      }
    }

Reproduction Steps

  1. Create 2 StateMachines
  2. Add a Task of type StepFunctionsStartExecution
stepfunctions_task.StepFunctionsStartExecution(
            scope=scope, id="EXAMPLE_STATE",
            state_machine=example_state_machine,
            input=stepfunctions.TaskInput.from_context_at("$$.Execution.Input"),
            integration_pattern=stepfunctions.IntegrationPattern.RUN_JOB,
            name="ExampleName")
  1. Execute the StateMachine more than once

The minimal amount of code should be something arround this lines.

class StateMachineTwo(aws_stepfunctions.StateMachine):
    def __init__(self,
                 scope: core.Construct) -> None:
        state__task = self._create_state__processing(scope=scope)

        super().__init__(
            scope=scope,
            id="StateMachineTwo",
            definition=state__task,
            timeout=core.Duration.minutes(5)
        )

    def _create_state__processing(self, scope):
        function = aws_lambda.Function(scope=scope, id="ExampleStateTwo", code=aws_lambda.Code().from_inline(
            """def handler(event, context):
                    return {}"""), handler="handler", runtime=aws_lambda.Runtime.PYTHON_3_7)
        return aws_stepfunctions_tasks.LambdaInvoke(scope=scope, id="EXAMPLE_STATE", lambda_function=function,
                                                    payload=aws_stepfunctions.Data.entire_payload)


class StateMachineOne(aws_stepfunctions.StateMachine):
    def __init__(self,
                 scope: core.Construct,
                 state_machine_two: StateMachineTwo) -> None:
        state__task = self._create_state__processing(scope=scope)
        state__stepfunction = self._create_state__processing_reversion(
            scope=scope, state_machine_two=state_machine_two)

        state__task.next(next=state__stepfunction)

        super().__init__(
            scope=scope,
            id="StateMachineOne",
            definition=state__task,
            timeout=core.Duration.minutes(5)
        )

    def _create_state__processing(self, scope):
        function = aws_lambda.Function(scope=scope, id="ExampleStateOne", code=aws_lambda.Code().from_inline(
            """def handler(event, context):
                    return {}"""), handler="handler", runtime=aws_lambda.Runtime.PYTHON_3_7)
        return aws_stepfunctions_tasks.LambdaInvoke(scope=scope, id="EXAMPLE_STATE", lambda_function=function,
                                                    payload=aws_stepfunctions.Data.entire_payload)

    def _create_state__processing_reversion(self, scope, state_machine_two):
        step_function_task = aws_stepfunctions_tasks.StepFunctionsStartExecution(
            scope=scope, id="STATE_ONE",
            state_machine=state_machine_two,
            input=aws_stepfunctions.Data.entire_payload,
            integration_pattern=aws_stepfunctions.IntegrationPattern.RUN_JOB)

        return step_function_task

Error Log

{ “error”: “StepFunctions.ExecutionAlreadyExistsException”, “cause”: “Execution Already Exists: ‘arn:aws:states:us-east-1:123456789:execution:StateMachineExample:EXAMPLE_STATE’ (Service: AWSStepFunctions; Status Code: 400; Error Code: ExecutionAlreadyExists; Request ID: abcd)” }

Environment

  • CLI Version : 1.47.0
  • Framework Version:
  • Node.js Version: 12.16
  • OS : Ubuntu
  • Language (Version): Python (3.7.6)

Other

I’m not sure if this classifies as Bug, or I’m failing to see something

I tried the following at the state machine in the AWS console, and execute it again, and it worked wonderfully.

"EXAMPLE_STATE": {
      "Next": "NEXT_EXAMPLE_STATE",
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync:2",
      "Parameters": {
        "Input.$": "$$.Execution.Input",
        "StateMachineArn": "arn:aws:states:us-east-X:123456789:stateMachine:ExampleStateMachine",
        "Name.$": "$.order.id"
      }
    }

The name of the nested StateMachine execution was the value of the order id.

I think if we can treat this name attribute like a normal Parameters attribute it would be a lot more powerful, because I can give the nested stepfunction a name that would allow me to tell apart an execution from another. For example, each execution has the ID of the order we send for shipping. So its easy to find and asses.


This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
shivlakscommented, Jun 30, 2020

I’m dropping the bug label from this as I believe JsonPath can be provided for the name property. If that’s not the case, let me know and we can revisit.

0reactions
shivlakscommented, Jul 23, 2020

@jindriago-scf that’s great that it worked! I think the README has an example. I’ll double check the doc string and make an update if needed to help any other users that run into similar friction

Read more comments on GitHub >

github_iconTop Results From Across the Web

class StepFunctionsStartExecution ... - AWS Documentation
If you set this property to true , the input property must be an object ... Type: string (optional, default: The entire task...
Read more >
AWS Step function string/json concatenation - Stack Overflow
I checked Input and Result path. They have this value. I can directly use this value as parameter. This is working fine. But...
Read more >
awsstepfunctionstasks - Go Packages
Find the set of states reachable through transitions from the given start state. This does not retrieve states from within sub-graphs, ...
Read more >
AWS Step Functions: JSONPath data processing - YouTube
JSONPath is introduced, and the InputPath, OutputPath, ResultPath, and DefaultPath fields are discussed for input and output processing in ...
Read more >
12: 9.15. JSON Functions and Operators - PostgreSQL
text[], json or jsonb, Get JSON object at the specified path ... The field/element/path extraction operators return NULL, rather than failing, if the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found