bug: Step Functions JSONPath filter projection loses its array shape for zero or one match #64
AndreKurait
started this conversation in
Bugs (AWS)
Replies: 2 comments
|
Hi @AndreKurait, thanks for raising this with us. I have escalated this issue to my engineers for a fix, so I will let you know as soon as we are ready for you to give it a try again. Please let me know if you have any questions or other issues in the meantime. |
0 replies
|
Hi @AndreKurait , this is now fixed in the |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Additional version check — 2026-10-08
Still reproduced: the nine-case projection/intrinsic matrix has the same results, including lost zero/singleton collection shape and the incorrect singleton nested-array result.
The comparison used an unmodified
localstack/localstack-pro:2026.8.1Linux ARM64 image,repository digest
sha256:4aef81c531684570d7b3cfd2805afa02194c929d52bbeedabb7d4874798b1572.Vendor packages were
localstack-core 2026.8.1,moto-ext 5.1.48, and bundledboto3/botocore 1.43.78. HTTP probes used a separateboto3/botocore 1.43.101client; the process-local security-group probe used the bundled interpreter.
The same scripts were used, with no custom extensions or provider source changes.
Owned test containers and the disposable network were removed.
This is a second specifically tested version, not a claim to have tested the latest release.
Existing report search
I searched the LocalStack issue tracker and current organization Discussions for this operation and failure. I did not find an existing report for this exact reproduction.
Current behavior
The following selection in a Pass state's Parameters loses the outer collection when a JSONPath filter matches zero or one nested field:
{ "matches.$": "$.items[?(@.key == 'keep')].payload.value", "first.$": "States.ArrayGetItem($.items[?(@.key == 'keep')].payload.value, 0)" }[]States.Runtimemissing-path error["one"]"one"["one", "two"]["one", "two"][["nested"]]["nested"][null]nullWith
ArrayGetItemadded, the singleton string and null cases fail. The singleton array case silently produces"nested"instead of["nested"]. The two-string case works.The attached script runs nine public API cases using two Pass-only Standard workflows on a fresh, unmodified LocalStack container. It does not test index zero of an empty array.
Expected behavior
A filter projection should retain its collection shape for zero, one, and multiple matches.
ArrayGetItemshould then select an element without losing that element's type. A one-element array containing an array or null is particularly useful for distinguishing projection cardinality from the selected value's type.References: Step Functions JSONPath and array intrinsics.
I have not run these cases on live AWS. The expected results are the intended JSONPath collection semantics; please flag any expression here that LocalStack considers outside supported Step Functions syntax. The report concerns filter projections followed by object fields, not all reference-path or literal-index behavior.
Environment
localstack/localstack-pro:2026.7.5.sha256:0d74e1d2d7ce13a3cb25fc64cf15eb225f1c95c762e56e057bc6a9ed0ed29306.localstack-core 2026.7.5,moto-ext 5.1.46,moto.__version__ = 5.1.21.dev,boto3/botocore 1.43.51.Fresh confirmation on 2026-10-08: the same discrepancy reproduced on Linux ARM64 against the same unmodified image, using a separate
boto3/botocore 1.43.101client. The disposable container and network were removed after the run. The startup block below includes the run's disabled DNS listener/default EC2-image downloads and temporary state storage; no provider source or extension was changed.Steps to reproduce
Start a disposable instance on a free loopback port:
Run the block in a disposable shell. Port 4567 must be free. The client needs
boto3; it uses only dummy credentials and a loopback endpoint. It creates disposable resources and cleans them up infinally; the shell trap removes the container even when the script reports failure. A nonzero exit is expected while the reported discrepancy is present. No Docker socket mount or application services are required.Complete standalone reproducer: stepfunctions_filter_arrays.py
All reactions