Skip to content

Bug: OPTIONS call returning 500 in HttpResolverLocal #8267

@Avinm

Description

@Avinm

Expected Behaviour

When cors=CORSConfig(...) is passed to HttpResolverLocal, browser preflight (OPTIONS) requests should return 204 with the appropriate Access-Control-* headers, just like APIGatewayRestResolver does.

Current Behaviour

OPTIONS requests fall through to _handle_not_found_async, which has no CORS preflight branch. They get treated as 404s, and because the not-found path uses lookup_exception_handler(NotFoundError) which walks the MRO, any generic @app.exception_handler(Exception) handler picks them up and returns 500 with no CORS headers. The browser then blocks the actual request.

Code snippet

import json
from aws_lambda_powertools.event_handler import HttpResolverLocal, Response
from aws_lambda_powertools.event_handler.api_gateway import CORSConfig

app = HttpResolverLocal(cors=CORSConfig(allow_origin="*"))

@app.post("/items")
def create_item():
    return {"ok": True}

@app.exception_handler(Exception)
def handle_server_error(ex: Exception):
    return Response(
        status_code=500,
        content_type="application/json",
        body=json.dumps({"error": "internal"}),
    )

Possible Solution

Mirror the CORS preflight branch from ApiGatewayResolver._handle_not_found into _handle_not_found_async:

if self._cors and self.current_event.http_method.upper() == "OPTIONS":
    headers = {
        "Access-Control-Allow-Methods": CORSConfig.build_allow_methods(self._cors_methods),
    }
    response = Response(status_code=204, content_type=None, headers=headers, body="")
else:
    # existing not-found logic

Steps to Reproduce

uvicorn app:app --port 3001
curl -i -X OPTIONS http://127.0.0.1:3001/items \
  -H 'Origin: http://localhost:3000' \
  -H 'Access-Control-Request-Method: POST'
# → 500, no Access-Control-* headers

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.10

Packaging format used

PyPi

Debugging logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Pending customer

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions