Skip to content

Bug: APIGatewayHttpResolver with validation enabled returns HTTP 422 when using single value query parameters #3732

Closed
@DariusKunce

Description

@DariusKunce

Expected Behaviour

When using Amazon Api Gateway REST API to invoke an AWS Lambda using proxy integration, calling API with a single query parameter should return HTTP 200 with Lambda Powertools validation enabled.

This is also how it is documented here: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#validating-query-strings

Current Behaviour

Calling API with GET /my-path?productType=Category1 returns HTTP 422:

{
    "statusCode": 422,
    "detail": [{
        "loc": ["query", "productType"], 
        "type": "type_error.str"
    }]
}

Code snippet

Bug can be reproduced with this code inside a Lambda function:


app = api_gateway.APIGatewayRestResolver(
    enable_validation=True
)

@app.get("/my-path")
def my_handler(
    product_type: Annotated[str | None, Query(alias="productType")] = None,
) -> api_gateway.Response[api_model.GetAvailableProductsResponse]:
    ...

Possible Solution

Can be fixed by changing query param type to list:

@app.get("/my-path")
def my_handler(
    product_type: Annotated[list[str] | None, Query(alias="productType")] = None,
) -> api_gateway.Response[api_model.GetAvailableProductsResponse]:
    """Lists available products"""
    ...

Steps to Reproduce

In AWS:

  1. Create a REST API in the Amazon Api Gateway Service.
  2. Create a Lambda function with Lambda Powertools configured as in the code examples.
  3. Configure the API Gateway with proxy integration to the Lambda function.
  4. Invoke the API with a query parameter.

Locally:

  1. Create unit tests for a Lambda function as described here: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#testing-your-code
  2. Run the test using REST API proxy integration payload. This payload always contains 2 attributes for the query string parameters, regardless if it's single value or multi value in REST API proxy integration:
    {
        ...
        "queryStringParameters": { "productType": "Category1" },
        "multiValueQueryStringParameters": { "productType": ["Category1"] }
    }

The issue is this line of code: https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py#L123

Lambda Powertools should additionally check dictionary values in multiValueQueryStringParameters if they contain only one value, and validate accordingly to be of type str instead of list[str].

Powertools for AWS Lambda (Python) version

2.33.0

AWS Lambda function runtime

3.12

Packaging format used

PyPi

Debugging logs

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Shipped

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions