Skip to content

Bug: OpenAPI schema inaccuracies (responses content, Pydantic Query models, ValidationError.msg, x- extensions, Path alias, Decimal NaN) #8583

Open

Description

@leandrodamascena

Expected Behaviour

The generated OpenAPI schema matches what the resolver validates and returns.

Current Behaviour

Six schema inaccuracies:

  1. responses={404: {"description": "nf"}} without content gets the handler's return model injected for every status code (openapi/schema_generator.py:506). A 404 documented as description-only is published as returning the model.
  2. A Pydantic model used as Query()/Header(): int | None, list[str] and Enum fields come out as {"type": "string"} (schema_generator.py:373, issubclass(Union, int) raises and falls back to string). Validation is correct, only the schema is wrong.
  3. The ValidationError component requires msg, which is neither in properties nor in the real 422 body (openapi/types.py:28). Every 422 response violates the published schema.
  4. openapi_extensions at root (api_gateway.py:1813) and operation level (schema_generator.py:403) skip the x- prefix check that Server and SecurityScheme enforce.
  5. Path(alias="ident") can never be satisfied (422 missing, openapi_validation.py:422 looks up field.alias but route args are keyed by the template name) and emits a parameter name not in the path template.
  6. Decimal("NaN") or Decimal("Infinity") in a response raises TypeError: '>=' not supported between 'str' and 'int' instead of SerializationError (openapi/encoders.py:330).

Code snippet

import decimal, json
from typing import Annotated
from pydantic import BaseModel
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.params import Path, Query
from tests.functional.utils import load_event

class Todo(BaseModel):
    id: int

class Q(BaseModel):
    limit: int | None = None
    tags: list[str] = []

app = APIGatewayRestResolver(enable_validation=True)

@app.post("/resp", responses={200: {"description": "ok", "content": {"application/json": {"model": Todo}}}, 404: {"description": "nf"}})
def resp() -> Todo: return Todo(id=1)

@app.get("/qm")
def qm(q: Annotated[Q, Query()]): return {}

@app.get("/pa/<id>", openapi_extensions={"foo": "bar"})
def pa(id: Annotated[int, Path(alias="ident")]): return {"id": id}

@app.get("/nf")
def nf(): return {"x": decimal.Decimal("NaN")}

s = json.loads(app.get_openapi_json_schema(openapi_extensions={"foo": "bar"}))
print(s["paths"]["/resp"]["post"]["responses"]["404"])        # has content -> Todo
print([(p["name"], p["schema"]) for p in s["paths"]["/qm"]["get"]["parameters"]])  # all "string"
print(s["components"]["schemas"]["ValidationError"]["required"])  # ['loc', 'msg', 'type']
print("foo" in s, "foo" in s["paths"]["/pa/{id}"]["get"])          # True True

ev = load_event("apiGatewayProxyEvent.json")
ev["path"] = "/pa/12"; print(app.resolve(ev, None)["statusCode"])   # 422
ev["path"] = "/nf"; app.resolve(ev, None)                           # TypeError

Possible Solution

Only fill content from the return type when resp_code == status_code; build field schemas with TypeAdapter(annotation).json_schema(); drop msg from required; validate the x- prefix in both places; look up path params by field.name or reject alias on Path; check Decimal.is_finite() and raise SerializationError.

Steps to Reproduce

Run the snippet above with the tests/events fixtures. Full context in #8576.

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.13

Packaging format used

PyPi

Debugging logs

Warning

This issue is ready to be picked up, by humans or by agents. If you want it, comment here first so we can assign it to you, and please take only one or two issues at a time so others can join in too. Thanks!

Activity

  1. added this to the 3.39.0 milestone on Oct 18, 2026
  2. SpinachDigital commented on Oct 19, 2026

    @SpinachDigital

    Taking this up — will open a PR shortly.

  3. leandrodamascena commented on Oct 19, 2026

    @leandrodamascena
    ContributorAuthor

    Hey @SpinachDigital pls go ahead, I saw #8630. Will review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions