Skip to content

feature request: Support of $context.requestOverride.status|querystring in apigateway #12621

Open
@pieronatan

Description

@pieronatan

Is there an existing issue for this?

  • I have searched the existing issues

Feature description

LocalStack does not currently support overriding:

  • responseOverride.status to set HTTP response status
  • requestOverride.querystring to inject query parameters into the integration request

Both work correctly in AWS API Gateway when using Velocity templates (VTL), but fail in LocalStack.


Examples

Override response status code (VTL):

#set($statusCode = $context.authorizer.statusCode)
#if($statusCode == 200)
    ##     Mapping the parameters from the request to the backend
    #foreach($param in $input.params().querystring.keySet())
        #set($context.requestOverride.querystring[$param]= $input.params().querystring.get($param))
        #if($foreach.hasNext) #end
    #end
    {
        "statusCode": 200,
        "message": "Valid scope found"
    }
#else
    #set($context.responseOverride.status = $statusCode)
    {
        "error": $context.authorizer.error
        "statusCode": $statusCode,
    }
#end

In AWS → returns HTTP 200.
In LocalStack → returns HTTP 200, or fails with:

2025-05-15T04:12:58.145  WARN --- [et.reactor-5] l.s.a.n.e.h.gateway_except : Non Gateway Exception raised: line 5, column 13: expected assignment in set directive, got: ($context.requestOverride.querystrin ... ...
 Traceback (most recent call last):
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 350, in require_next_element
     element = element_spec(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1077, in parse
     (var_name,) = self.identity_match(self.START)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 306, in identity_match
     raise NoMatch()
 airspeed.operators.NoMatch
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/rolo/gateway/chain.py", line 166, in handle
     handler(self, self.context, response)
   File "/opt/code/localstack/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_request.py", line 119, in __call__
     body, request_override = self.render_request_template_mapping(
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_request.py", line 186, in render_request_template_mapping
     body, request_override = self._vtl_template.render_request(
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/localstack-core/localstack/services/apigateway/next_gen/execute_api/template_mapping.py", line 193, in render_request
     result = self.render_vtl(template=template.strip(), variables=variables_copy)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/localstack-core/localstack/utils/aws/templating.py", line 119, in render_vtl
     rendered_template = t.merge(namespace)
                         ^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 92, in merge
     self.merge_to(namespace, output, loader)
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 102, in merge_to
     self.ensure_compiled()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 97, in ensure_compiled
     self.root_element = TemplateBody(self.filename, self.content)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1351, in parse
     self.block = self.next_element(Block)
                  ^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 333, in next_element
     element = element_spec(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1368, in parse
     self.next_element(
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 339, in next_element
     element = element_class(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1043, in parse
     self.block = self.require_next_element(Block, "block")
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 350, in require_next_element
     element = element_spec(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1368, in parse
     self.next_element(
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 339, in next_element
     element = element_class(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1312, in parse
     self.block = self.next_element(Block)
                  ^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 333, in next_element
     element = element_spec(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1368, in parse
     self.next_element(
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 339, in next_element
     element = element_class(self.filename, self._full_text, self.end)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 289, in __init__
     self.parse()
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 1291, in parse
     self.assignment = self.require_next_element(Assignment, "assignment")
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/opt/code/localstack/.venv/lib/python3.11/site-packages/airspeed/operators.py", line 352, in require_next_element
     raise self.syntax_error(expected)
 airspeed.operators.TemplateSyntaxError: line 5, column 13: expected assignment in set directive, got: ($context.requestOverride.querystrin ... ...

Environment

  • LocalStack version: latest
  • Running via: Docker / Compose / CLI
  • Infrastructure: Terraform / AWS CLI

🧑‍💻 Implementation

No response

Anything else?

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions