localstack icon indicating copy to clipboard operation
localstack copied to clipboard

bug: TestState variables not interpolated in Pass state(applies to other supported states as well) with JSONata

Open kollirajesh opened this issue 3 months ago • 1 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

Current Behavior

The TestState API, when used with variables, fails to interpolate the variable values into the state definition's Result field, even when the QueryLanguage is set to JSONata. The TestStateResponse.output() contains the literal JSONata reference ({% $variableName %}) rather than the expected value from the variables payload.

In the response, variables is null in inspectionData object.

Expected Behavior

When a TestState request includes a variables payload and the state definition explicitly sets QueryLanguage: JSONata, the TestState API should correctly interpolate these variables. The TestStateResponse.output() should reflect the result of this interpolation, containing the variable's value instead of its JSONata reference. For example, {% $executionHttpCode %} should be replaced by "204".

How are you starting LocalStack?

With the localstack script

Steps To Reproduce

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

LocalStackContainer localStackContainer;

localStackContainer.start()

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

   String stateDefinition = """
                {
                  "Type" : "Pass",
                  "Comment" : "Prepare the payload for the Test action result",
                  "Output" : {
                    "headers" : {
                      "ce_id" : "{% $states.context.Execution.Input.headers.ce_id %}",
                      "ce_source" : "{% $states.context.Execution.Input.headers.ce_source %}",
                      "ce_type" : "{% $states.context.Execution.Input.headers.ce_type %}",
                      "traceparent" : "{% $states.context.Execution.Input.headers.traceparent %}"
                    },
                    "payload" : {
                      "requestDetail" : {
                        "actionData" : "{% $states.context.Execution.Input.payload.actionData %}"
                      },
                      "resultDetail" : {
                        "executionHttpCode" : "{% $exists($executionHttpCode) ? $executionHttpCode : '501' %}",
                        "retryCount" : "{% $exists($apiCallCounter) ? $apiCallCounter - 1 : '0' %}"
                      }
                    }
                  },
                  "QueryLanguage" : "JSONata",
                  "End" : true
                }""";

    String input = """
            {
              "headers" : {
                "ce_id" : "877efd3f-a3ce-4b7e-d943-342e851bf4e9",
                "ce_source" : "/test/casemanagement",
                "ce_type" : "actionsrequest.event.v1.0",
                "traceparent" : "00-8d8bfd5cb598446daafcceee857b4be8-8c7b9aa7cc664944-01"
              },
              "payload" : {
                "partyID" : "94EFDA8C685E45F1D200DCEDEBE5F4097060CEC241B5J50A6478D02D4CEE7B30",
                "actionType" : "USER_PROFILE_TEST",
                "actionData" : "00u2tl4fq32KEXscU0h9"
              }
            }""";

    String variables = """
            {
              "executionHttpCode": 204,
              "retryCount": 1
            }""";

    TestStateRequest testStateRequest = TestStateRequest.builder()
            .definition(stateDefinition)
            .input(input)
            .variables(variables)
            .inspectionLevel(InspectionLevel.DEBUG)
            .build();

    TestStateResponse response = client.testState(testStateRequest);

    JsonNode responseJson = new ObjectMapper().readTree(response.output());
    int executionHttpCode = responseJson.at("/payload/resultDetail/executionHttpCode").asInt();
    int expectedRetryCount = responseJson.at("/payload/resultDetail/retryCount").asInt();
    assertThat(executionHttpCode).isEqualTo(204);
    assertThat(expectedRetryCount).isEqualTo(1);

Environment

- OS:mac os 15.7 (24G222)
- LocalStack:
  LocalStack version:4.8.1
  Container: localstack/localstack:4.8.1
  Service: Step Functions - AWS Java SDK :: Services :: AWS Step Functions, version: 2.34.6 or later

Anything else?

No response

kollirajesh avatar Oct 01 '25 16:10 kollirajesh

Welcome to LocalStack! Thanks for reporting your first issue and our team will be working towards fixing the issue for you or reach out for more background information. We recommend joining our Slack Community for real-time help and drop a message to LocalStack Support if you are a licensed user! If you are willing to contribute towards fixing this issue, please have a look at our contributing guidelines.

localstack-bot avatar Oct 01 '25 16:10 localstack-bot