Skip to content

fix(stepfunctions): resolve JSONata $merge regression with dynamic args#13717

Open
shubhiscoding wants to merge 2 commits intolocalstack:mainfrom
shubhiscoding:fix-jsonata-merge-variable-extraction
Open

fix(stepfunctions): resolve JSONata $merge regression with dynamic args#13717
shubhiscoding wants to merge 2 commits intolocalstack:mainfrom
shubhiscoding:fix-jsonata-merge-variable-extraction

Conversation

@shubhiscoding
Copy link
Contributor

Fixes #13579

Motivation

Since v4.12, the JSONata $merge() function returns {} when merging objects
from dynamic input references like $states.input.part1. Static values work fine.

Changes

  • Removed the bracket expression branch from the variable reference regex in
    jsonata.py. This branch was consuming variable references inside JSONata
    array literals [...], preventing them from being bound to actual values.

    The bracket branch was redundant — its purpose was to prevent false $ captures inside bracket notation like $states.input["field-name"], but this case is already handled by branch 2 (string literal skipper), which consumes the "field-name" before the variable branch can see it. All other Step Functions JSONata operations (string literals, regex literals, bracket field access, filter expressions) continue to work correctly without it.

  • Added unit tests for extract_jsonata_variable_references covering array
    literals, bracket field access, string/regex literals, and edge cases.

Tests

  • Unit tests: pytest tests/unit/services/stepfunctions/test_jsonata_variable_references.py
  • Integration tests: pytest tests/aws/services/stepfunctions/v2/evaluate_jsonata/
  • Manual reproduction: $merge([$states.input.part1, $states.input.part2]) now returns merged result
image

Related

@shubhiscoding
Copy link
Contributor Author

Hey guys the pr is ready for review, would really like for someone to take a look at it please

Copy link
Contributor

@tiurin tiurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shubhiscoding, thank you for looking into the issue and providing a PR! We will review it shortly. Non-capturing branch was added recently, let us review the reason for that change first.

Immediate feedback on tests: the preferred way of testing the changes is with AWS parity tests. While unit tests make sense in some cases, adding a validated snapshot test to tests/aws/services/stepfunctions/v2/evaluate_jsonata that fails before the change and passes after it would guarantee the parity with AWS.

@shubhiscoding
Copy link
Contributor Author

Hii @tiurin Thanks for the feedback! I've added an AWS-validated snapshot test (test_merge_with_dynamic_args) in tests/aws/services/stepfunctions/v2/evaluate_jsonata/

Kept the unit tests as well since they directly test the regex extraction and are fast to run, but happy to remove them if you'd prefer only the snapshot test.

Let me know if any other changes are needed!

@tiurin tiurin added aws:stepfunctions AWS Step Functions semver: patch Non-breaking changes which can be included in patch releases docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes labels Feb 11, 2026
Copy link
Contributor

@tiurin tiurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shubhiscoding Thanks for addressing comment about parity tests, nice work!

I've approved CI pipeline runs for this PR. On the first run all jobs failed because a significant change has just been introduced. Please rebase this branch onto the latest main to make CI execute checks correctly.

Meanwhile, I've run step functions test suite locally on this branch and unfortunately the fix introduces another regression. See comment below for the details.

# allowing escapes
r"(?:\"(?:\\.|[^\"\\])*\"|\'(?:\\.|[^\'\\])*\')"
r"|"
# 3) Non-capturing branch for bracket expressions [...]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been added while working on adding new capabilities to TestState API. Removing it makes test_map_state_failure_count test fail:


Specifically, the one that uses map_task_state state machine template.

While the change introduced regression, simply removing it will introduce another one. Let's try to find a solution that makes all existing tests pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aws:stepfunctions AWS Step Functions docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes semver: patch Non-breaking changes which can be included in patch releases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: JSONata merge function fails on dynamic arguments since version 4.12

2 participants