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 workingpending-releaseFix or implementation already in dev waiting to be released

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Coming soon

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions