Repository navigation
Summary
This release fixes seventeen bugs across Parameters, Event Handler, Circuit Breaker, Parser, Data Classes and the shared cache, and corrects a handful of docs. There are only a small new feature, but no new utility this time: we spent the cycle paying down the bugs we had found in our own audits, and the community did most of the paying.
The community is still on fire. We opened the audit findings as good first issue on a Saturday, and by Monday every one of them had a pull request. Nineteen PRs merged, sixteen people, one of them for the third release in a row. Thank you all.
Welcome to our fourteen new contributors: @yagruda, @wanjinhao1, @Golden007-prog, @SuellenQwQ, @MrForward, @Tanmay-Ts, @kudala-bharani, @Suraj1347, @SpinachDigital, @jasperdingg, @Vl4dC, @ShussMiao, @ASHMEET555 and @Manishram-ai. Thanks also to @SumiRann1 for finishing the cache key work started in 3.38.0, and to @vishwakt for a third fix in a row.
One heads-up: Python 3.10 reached end of life and Lambda deprecated the python3.10 runtime on October 31, 2026. We stop supporting Python 3.10 on February 1, 2027. Details and the command to list your functions still on it are in #8735.
Parameters
Eight fixes, most of them the long tail of get_parameters_by_name and caching after the 3.38.0 changes:
get()andget_parameters_by_name()now share cache entries: a parameter fetched one way is served from cache the other way, and aSecureStringfetched withdecrypt=Trueis never served to a call without it.set_parameterandset_secretinvalidate the cached value, so the next read returns what you just wrote instead of the old value for up tomax_age.- A transform that fails inside
get_parameters_by_namewithraise_on_error=Falselands in_errorsand is not cached, so a corrected parameter stops returningNoneuntil the cache expires. Note for anyone who checked forNone: the failed name is now omitted from the result instead. GetSecretErroris a subclass ofGetParameterError, so oneexcept GetParameterErrorcovers secrets too.- Every
GetParametersclient error is wrapped asGetParameterError(or listed in_errors), not onlyInvalidKeyIdandInternalServerError. DynamoDBProviderraisesGetParameterErrorwith a clear message for a missing item or a wrongsort_attr, instead ofKeyError; the AppConfig provider says which configuration is empty.- A
SecretBinarythat is not valid UTF-8 staysbyteswithout a transform and raisesTransformParameterErrorwith one, instead ofUnicodeDecodeError. SecretsProvider.get_multipleno longer appends to theFilterslist you pass in.
Event Handler
- Header validation is consistent across REST API, HTTP API, ALB, Function URL and VPC Lattice:
list[str]headers accept comma-separated values, repeated header lines are joined for scalar parameters, and+jsonmedia types such asapplication/problem+jsonare accepted as JSON bodies. - Six OpenAPI schema fixes: description-only responses no longer inherit the handler's return schema, Pydantic
Query()andHeader()fields render their real types,ValidationErrorno longer requires amsgit does not emit,Path(alias=...)validates and renders by the template name, and non-finiteDecimalvalues raiseSerializationError. Anopenapi_extensionskey without thex-prefix now emits aPowertoolsUserWarning; it becomes an error in the next major. - Seven smaller fixes: Bedrock Agents ignore query parameters that are not in the handler signature with validation off and default the response media type to
application/json; the AppSync Events registry returns the function when the path is invalid; the AppSync resolver clears its context even when an exception handler answers;Routerwarns on duplicate routes like the resolver does; andDepends(SomeClass)injectsRequestand nested dependencies declared on__init__. AppSyncEventsResolverwithaggregate=Falsere-raisesUnauthorizedException, so AppSync returns 401 instead of a 200 with an error payload. Class-based middlewares with anasynchandler are awaited underresolve_async.HttpResolverLocalworks as a Lambda handler for REST, HTTP API v2 and Function URL events, not only as an ASGI app.
Circuit Breaker
@circuit_breaker now supports async def functions. The coroutine is awaited inside the circuit, so failures count towards failure_threshold, probes run on the awaited result, and on_circuit_open can be a coroutine function. While testing it we also found that concurrent coroutines in one event loop could all run the half-open probe at once, because the probe owner id is per thread; a probe now runs once per process, and the other callers get the open response, the same guarantee threads already had. Thank you @ASHMEET555.
Other fixes
LRUDict.gethonours its default and refreshes recency, so falsy cached values are returned and the least recently used entry is the one evicted.CloudWatchAlarmMetric.metric_statreturnsNonefor metric math expression entries instead of raising.- The six IoT Core registry models import from
aws_lambda_powertools.utilities.parser.modelslike every other built-in model.
Changes
- fix(parameters): use shared cache key in get_parameters_by_name (#8614) by @SumiRann1
- fix(cache): preserve LRUDict.get defaults and LRU order (#8683) by @Vl4dC
- fix(data_classes): return None from CloudWatchAlarmMetric.metric_stat for expression entries (#8691) by @ShussMiao
- fix(event_handler): make HttpResolverLocal usable as a Lambda handler (#8634) by @jasperdingg
- fix(event_handler): propagate UnauthorizedException and await async class-based middlewares (#8633) by @SuellenQwQ
- fix(event_handlers): Bedrock kwargs and media type, AppSync registry and context, Router duplicates, Function URL base path, Depends with classes (#8629) by @vishwakt
- fix(event_handler): correct six OpenAPI schema inaccuracies (#8630) by @SpinachDigital
- fix(event_handler): unify header validation, scalar list joining, and content-type parsing (#8602) by @yagruda
- fix(parameters): invalidate cache after set_parameter and set_secret (#8622) by @Suraj1347
- fix(parameters): handle transform failures gracefully in get_parameters_by_name (#8623) by @Suraj1347
- fix(parameters): handle invalid UTF-8 transform errors (#8609) by @Golden007-prog
- fix(parameters): clarify errors for missing DynamoDB and AppConfig data (#8618) by @kudala-bharani
- fix(parameters): wrap GetParameters client errors in get_parameters_by_name (#8617) by @Tanmay-Ts
- fix(parameters): do not mutate the caller's Filters list in SecretsProvider.get_multiple (#8604) by @wanjinhao1
- fix(parameters): make GetSecretError inherit from GetParameterError (#8611) by @MrForward
📜 Documentation updates
- fix(parser): add IoT Core registry models to parser.models exports (#8746) by @Manishram-ai
- docs: fix dead Pants and uvicorn links (#8760) by @Manishram-ai
- chore(deps): bump python from
a6e34c5tof17ec84in /docs (#8737) by @dependabot[bot] - chore(deps): bump pydantic, pytest, nox, type stubs, zensical, aws-cdk and setup-uv (#8756) by @leandrodamascena
- docs: refresh the README and the feature table (#8733) by @leandrodamascena
- docs: write down the project premises, add AGENTS.md and the AI-assisted contribution policy (#8717) by @leandrodamascena
- feat(circuit_breaker): await async coroutines inside circuit breaker failure tracking (#8703) by @ASHMEET555
- docs(parameters): correct the documented default of recursive per provider (#8610) by @SuellenQwQ
🔧 Maintenance
- chore(deps): bump python from
a6e34c5tof17ec84in /docs (#8737) by @dependabot[bot] - chore(deps-dev): bump filelock from 4.0.3 to 4.1.0 (#8758) by @dependabot[bot]
- chore(deps): bump pydantic, pytest, nox, type stubs, zensical, aws-cdk and setup-uv (#8756) by @leandrodamascena
- docs: write down the project premises, add AGENTS.md and the AI-assisted contribution policy (#8717) by @leandrodamascena
This release was made possible by the following contributors:
@ASHMEET555, @Golden007-prog, @jasperdingg, @kudala-bharani, @leandrodamascena, @Manishram-ai, @MrForward, @ShussMiao, @SpinachDigital, @SuellenQwQ, @SumiRann1, @Suraj1347, @Tanmay-Ts, @vishwakt, @Vl4dC, @wanjinhao1, @yagruda, @dependabot[bot] and @claude