Skip to content

v3.39.0

Latest

Choose a tag to compare

@github-actions github-actions released this 03 Nov 13:56
· 2 commits to develop since this release

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() and get_parameters_by_name() now share cache entries: a parameter fetched one way is served from cache the other way, and a SecureString fetched with decrypt=True is never served to a call without it.
  • set_parameter and set_secret invalidate the cached value, so the next read returns what you just wrote instead of the old value for up to max_age.
  • A transform that fails inside get_parameters_by_name with raise_on_error=False lands in _errors and is not cached, so a corrected parameter stops returning None until the cache expires. Note for anyone who checked for None: the failed name is now omitted from the result instead.
  • GetSecretError is a subclass of GetParameterError, so one except GetParameterError covers secrets too.
  • Every GetParameters client error is wrapped as GetParameterError (or listed in _errors), not only InvalidKeyId and InternalServerError.
  • DynamoDBProvider raises GetParameterError with a clear message for a missing item or a wrong sort_attr, instead of KeyError; the AppConfig provider says which configuration is empty.
  • A SecretBinary that is not valid UTF-8 stays bytes without a transform and raises TransformParameterError with one, instead of UnicodeDecodeError.
  • SecretsProvider.get_multiple no longer appends to the Filters list 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 +json media types such as application/problem+json are accepted as JSON bodies.
  • Six OpenAPI schema fixes: description-only responses no longer inherit the handler's return schema, Pydantic Query() and Header() fields render their real types, ValidationError no longer requires a msg it does not emit, Path(alias=...) validates and renders by the template name, and non-finite Decimal values raise SerializationError. An openapi_extensions key without the x- prefix now emits a PowertoolsUserWarning; 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; Router warns on duplicate routes like the resolver does; and Depends(SomeClass) injects Request and nested dependencies declared on __init__.
  • AppSyncEventsResolver with aggregate=False re-raises UnauthorizedException, so AppSync returns 401 instead of a 200 with an error payload. Class-based middlewares with an async handler are awaited under resolve_async.
  • HttpResolverLocal works 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.get honours its default and refreshes recency, so falsy cached values are returned and the least recently used entry is the one evicted.
  • CloudWatchAlarmMetric.metric_stat returns None for metric math expression entries instead of raising.
  • The six IoT Core registry models import from aws_lambda_powertools.utilities.parser.models like 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

🔧 Maintenance

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