Skip to content

Releases: aws-powertools/powertools-lambda-typescript

v2.36.0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 16:47
v2.36.0
0595159

Summary

In this release, we've expanded the Lambda layer to include all 14 published Powertools packages. Data Masking, Signer, Kafka, and Validation are now available directly from the layer, making it easier to use these utilities without bundling the Powertools packages separately.

Important for Lambda layer users: We've changed how the layers are built and no longer include the AWS SDK for JavaScript v3 clients we previously bundled. We still recommend bundling the SDK packages your function needs so you control their versions. Your bundled SDK takes precedence; if you don't bundle one, Powertools falls back to the SDK provided by the Lambda Node.js runtime. Remove any build exclusions that assumed the Powertools layer supplied the SDK.

We've also made JSON-only Kafka consumers easier to bundle and added Parser support for WITH_METADATA deliveries from the new enhanced Custom Event Bus in Amazon EventBridge.

We've fixed Valkey-backed idempotency when using @valkey/valkey-glide. Previously, the persistence layer passed Redis-client write options that Glide ignored, so records and locks could be written without expiry or conditional-write protection. The persistence layer now passes the correct options, restoring the expected record expiry and protection against duplicate processing. If you use Valkey Glide, we recommend upgrading.

Other Idempotency fixes keep operations tied to the correct record when your handler modifies its input or multiple idempotent functions share a persistence instance, preventing stuck in-progress records and incorrect updates. The HTTP Event Handler also preserves binary response bodies and correctly handles responses with no body, so you can serve files or return 204 No Content without workarounds.

This release also includes several other bug fixes, minor improvements, and documentation updates, with the help of the community.

⭐ Congratulations to @pttydou, @vaibhav8a, @sabaighani, @vahidshaik1901, @Provokke, @victoriademina, @proton0210, and @karthiksenv for their first PRs merged in the project, and thanks to @vishwakt for their many contributions to this release 🎉

More utilities in the Lambda layer

Docs

The Lambda layer now includes all 14 published Powertools packages. Data Masking, Signer, Kafka, and Validation were previously missing, so you can now use those utilities from the layer rather than bundling the Powertools packages separately.

The layer also no longer bundles AWS SDK v3 clients. This avoids mixing layer-provided clients with a different SDK version from the Lambda runtime, which could cause failures when using the DynamoDB DocumentClient.

EventBridge Custom Event Bus support

Docs

Parser now supports WITH_METADATA subscriber deliveries from the new enhanced Custom Event Bus in Amazon EventBridge, which is distinct from Custom Event Bus – Classic. Each delivered record contains the event in Data, optional custom metadata in Metadata, and delivery information in SystemMetadata, such as whether the event is live or replayed.

import { parse } from '@aws-lambda-powertools/parser';
import { EventBridgeWithMetadataEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { z } from 'zod';

const orderSchema = z.object({
  orderId: z.string(),
  amount: z.number(),
});

export const handler = async (event: unknown) => {
  const orders = parse(event, EventBridgeWithMetadataEnvelope, orderSchema);
  return orders;
};

Use EventBridgeWithMetadataRecordSchema or EventBridgeWithMetadataSchema when you need to retain the event and its metadata. The record schema also supports single-object deliveries.

Simpler Kafka bundles

Docs

If your Kafka consumer only handles JSON, you no longer need to install avro-js and protobufjs just to make your function bundle successfully. These libraries are now optional dependencies loaded only when their corresponding format is configured, so you can leave unused codecs out of your deployment.

If you use Avro or Protocol Buffers, install the corresponding library and include it in your deployment.

Changes

  • chore(deps): apply available npm audit fixes (#5790) by @svozza
  • test(batch): add Lambda Managed Instances isolation coverage (#5768) by @karthiksenv
  • fix(parser): accept real Cognito trigger events from common flows (#5777) by @vishwakt
  • docs(parser): fix schema names in built-in schemas table (#5784) by @vishwakt
  • feat(parser): support EventBridge WITH_METADATA deliveries (#5776) by @proton0210
  • refactor(idempotency): make DynamoDB error check minification-resistant (#5775) by @dreamorosi
  • fix(parser): accept multi-value headers in VPC Lattice v2 events (#5773) by @vishwakt
  • fix(parser): accept documented SES receipt event variants (#5772) by @vishwakt
  • fix(parser): keep PhysicalResourceId in CloudFormation events (#5767) by @proton0210
  • refactor(tracer): track fetch subsegments per request (#5746) by @victoriademina
  • fix(idempotency): pass cache SET options in the Valkey Glide shape (#5737) by @Provokke
  • fix(tests): deterministic LMI e2e overlap and capacity provider headroom (#5736) by @svozza
  • fix(parser): keep transform errors as the ParseError cause (#5745) by @svozza
  • fix(parser): keep Lambda authorizer context in the REST API event schema (#5749) by @vishwakt
  • fix(idempotency): bind operations to their own key prefix on a shared store (#5708) by @svozza
  • fix(batch): throw when a synchronous processor gets a promise-returning handler (#5650) by @vahidshaik1901
  • fix(event-handler): honor Accept-Encoding q-values in compression (#5725) by @arnabrahman
  • fix(idempotency): complete and delete the record acquired at operation start (#5717) by @vishwakt
  • fix(idempotency): keep payload validation hash on cache record completion (#5706) by @svozza
  • fix(event-handler): handle empty proxy response bodies (#5701) by @svozza
  • fix(event-handler): preserve binary Web Response bodies (#5700) by @svozza
  • chore(tests): split custom Vitest matchers out of setupEnv (#5704) by @svozza
  • fix(event-handler): stop recursive HTTP error handler dispatch (#5703) by @svozza
  • chore(tests): centralise TypeScript test configuration (#5695) by @svozza
  • refactor(event-handler): simplify HTTP event parsing (#5686) by @svozza
  • chore(tests): replace aws-sdk-client-mock-vitest with local matcher (#5693) by @svozza
  • fix(ci): skip unrelated release workflows without approval (#5688) by @svozza
  • fix(event-handler): ignore body on GET/HEAD requests when converting to Web Request (#5683) by @sabaighani
  • fix(idempotency): retain cache locks without execution deadlines (#5680) by @svozza
  • chore(tests): add Metrics e2e suite for Lambda Managed Instances (#5663) by @svozza
  • fix(idempotency): delete only acquired records in the Middy onError hook (#5676) by @svozza
  • fix(event-handler): honour isBase64Encoded and binary bodies on proxy results (#5668) by @svozza
  • chore(ci): align cached-node-modules pins and drop a stale header comment (#5665) by @svozza
  • chore(ci): remove the unused Publish Package workflow (#5664) by @svozza
  • fix(parser): stop malformed base64 from escaping safeParse (#5666) by @vishwakt
  • docs(maintenance): explain how to test invocation-scoped state (#5661) by @svozza
  • fix(ci): harden the release manifest patch and e2e sweep incident lookup (#5662) by @svozza
  • chore(maintenance): pin Python 3.14 across the docs toolchain (#5648) by @svozza
  • chore(maintenance): align CI matrices and repository templates (#5635) by @dreamorosi
  • chore(ci): derive workflow matrices from the root workspaces list (#5638) by @svozza
  • fix(maintenance): normalize package test scripts (#5653) by @dreamorosi
  • chore(ci): convert the scripts in .github/scripts to ESM (#5640) by @svozza
  • chore(maintenance): retire sample application (#5634) by @dreamorosi
  • docs(maintenance): retire stale process docs (#5618) by @dreamorosi
  • chore(maintenance): make the root tsconfig an options base with no program (#5646) by @svozza
  • fix(event-handler): fail invocation on UnauthorizedException in onPublish (#5621) by @svozza
  • fix(data-masking): honor throwOnMissingField consistently and resolve paths before masking (#5630) by @svozza
  • fix(batch): populate response() before full batch throw and normalize non-Error throws (#5625) by @svozza
  • fix(parameters): include request options in cache key (#5623) by @svozza
  • refactor(commons): extract InvokeStore fallback into InvocationScoped (#5615) by @dreamorosi
  • chore(deps): bump click to 8.3.3 in docs requirements (#5616) by @dreamorosi
  • chore(ci): auto-merge non-major Dependabot GitHub Actions updates (#5608) by @svozza
  • docs: add CODING_STANDARDS.md agent-facing coding reference (#5598) by @dreamorosi
  • chore(tests): add scheduled sweeper for leaked e2e infrastructure (#5599) by @dreamorosi
  • chore(layers): replace shell filesystem commands (#5596) by @dreamorosi
  • chore(tests): add LMI e2e suite and run-scoped shared capacity provider (#5465) by @svozza
  • chore(maintenance): move dev tooling to devDependencies in private workspaces (#5595) by @svozza
  • ci(maintenance): auto-merge Dependabot dev dependency updates (#5568) by @svozza
  • fix(layers): bundle all publishable utilities in the Lambda layer (#5577) by @svozza
  • fix(kafka): lazily import Avro and Protobuf codecs so JSON-only con...
Read more

v2.35.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 16:41
7bcc27b

Summary

In this release, the Parameters utility gains support for the AWS AppConfig Agent Lambda extension. A new getConfig function fetches application configurations from the agent's local HTTP endpoint, without the AWS SDK and without a cache to manage, since caching, polling, and prefetching are all handled by the agent.

In Logger, the log buffer and the debug sampling log level are now scoped per invocation under Lambda Managed Instances concurrency, so concurrent invocations no longer clear each other's buffered logs or override each other's sampling decision. Logger also now accepts IANA timezone aliases such as Asia/Kolkata in the TZ environment variable, which were previously rejected and produced timestamps for the wrong instant. When a timezone can't be resolved at all, Logger now falls back to UTC consistently and emits a warning, instead of doing so silently.

The Parser utility adds a schema for Amazon Connect Outbound Campaigns custom action events.

Finally, the documentation site has been restyled to match the AWS Developer Guide.

Important

The project's Discord server has been shut down. Community conversations now happen in GitHub Discussions, and all Discord links in the READMEs, docs, and issue templates now point there.

⭐ Congratulations to @leiwilson for their first PR merged in the project 🎉

AppConfig Agent support

If you use the AWS AppConfig Agent Lambda extension, you can now fetch application configurations from the agent's local HTTP endpoint with getConfig:

import { getConfig } from '@aws-lambda-powertools/parameters/appconfig-agent';

const config = await getConfig('my-configuration', {
  environment: 'my-env',
  application: 'my-app',
  transform: 'json',
});

export const handler = async (): Promise<void> => {
  console.log(config);
};

A few things to know:

  • You must add the AppConfig Agent Lambda extension layer to your function. getConfig talks to it over the agent's local endpoint, so it doesn't need the AWS SDK.
  • Because the agent handles caching, polling, and prefetching, the maxAge and forceFetch options don't apply. You can reduce cold start latency by setting AWS_APPCONFIG_EXTENSION_PREFETCH_LIST so the agent fetches your configuration before your handler runs.
  • When the configuration doesn't exist, getConfig returns undefined, so you can fall back with ??, or set throwOnMissing to get a ParameterNotFoundError instead. Any other failure to reach the agent throws a GetParameterError.
  • Outside of Lambda, or when POWERTOOLS_DEV is enabled, getConfig returns undefined without making a request, so your tests never need to mock the agent. Set POWERTOOLS_APPCONFIG_AGENT_RETURN_VALUE when you want it to return a value instead.

Changes

  • refactor(logger): isolate log level InvokeStore access in a store (#5548) by @vishwakt
  • fix(logger): scope log buffer per invocation under LMI concurrency (#5543) by @vishwakt
  • fix(logger): scope debug sampling log level per invocation under LMI concurrency (#5544) by @vishwakt
  • chore(ci): remove boring-cyborg and semantic config files (#5535) by @dreamorosi
  • chore(ci): remove greetings now handled by oss-automation (#5532) by @dreamorosi
  • chore: replace Discord server with GitHub Discussions (#5530) by @dreamorosi
  • docs: restyle documentation to match AWS Developer Guide (#5426) by @dreamorosi
  • chore(ci): group CodeQL Action Dependabot updates (#5521) by @dreamorosi
  • docs(metrics): document InvokeStore isolation and local testing (#5486) by @leiwilson
  • ci: replace CodeQL default setup with advanced setup for fork PRs (#5507) by @svozza
  • feat(parser): add schema for Amazon Connect Outbound Campaigns (#5502) by @dreamorosi
  • feat(ci): auto-trigger make-release and docs rebuild on PR merge (#5487) by @svozza
  • feat(ci): fold GovCloud/China layer publishing into Make Release (#5462) by @svozza
  • feat(parameters): add support for AppConfig Agent (#5399) by @svozza
  • chore: clean up issue templates (#5470) by @dreamorosi
  • chore(ci): remove SonarCloud integration (#5468) by @dreamorosi
  • docs(readme): add Signer, Data Masking, and Kafka utilities (#5464) by @svozza
  • fix(logger): accept resolvable IANA timezone aliases in timestamps (#5458) by @dreamorosi
  • fix(ci): skip paused regions in update_layer_arn.sh (#5457) by @dreamorosi
  • docs(maintainers): remove stale layer version note-taking instruction (#5454) by @svozza

🔧 Maintenance

Read more

v.2.34.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 15:00
e8cff7f

Summary

This release introduces two new utilities: Signer, for signing HTTP requests to AWS services with SigV4, and Data Masking, for encrypting, decrypting, or irreversibly erasing sensitive fields in your event data.

We've also fixed three bugs affecting Logger and Tracer under [Lambda Managed Instances](https://docs.aws.amazon.com/lambda/latest/dg/managed-instances.html(LMI) concurrency, where multiplexing several invocations into the same execution environment could cause log lines and X-Ray trace data from one invocation to leak into another.

On top of that, Metrics now supports automatic flushing via the using keyword, Parameters gained an opt-in throwOnMissing option to fail fast on missing values, and Idempotency now warns when a shared persistence layer instance receives a reconfiguration it silently ignores. We've also fixed a Metrics bug where a metric name colliding with a dimension or metadata key could silently corrupt the CloudWatch EMF payload, along with a couple of HTTP Router fixes: a crash affecting bundles that don't install Metrics, and unreachable routes caused by trailing slashes.

⭐ Congratulations to @kimnamu for their first PR merged in the project and thank you to @vishwakt and @Zelys-DFKH for their contributions too. 🎉

Signer

The new @aws-lambda-powertools/signer package signs HTTP requests using AWS Signature Version 4 (SigV4), so you can call IAM-authenticated endpoints — API Gateway, Lambda function URLs, AppSync — from within your Lambda functions.

Signing and sending are kept separate: SigV4Signer signs a web-standard Request and performs no network I/O, while createSignedFetcher gives you a drop-in signed fetch for when you just want to sign and send in one step. By default, the signer reads credentials and region from the Lambda runtime environment, so no extra dependencies or configuration are required.

import { SigV4Signer } from '@aws-lambda-powertools/signer/sigv4';

const signer = new SigV4Signer({ service: 'execute-api' });

export const handler = async () => {
  const signed = await signer.sign(
    'https://example.execute-api.us-east-1.amazonaws.com/items'
  );

  // `signed` is a standard `Request` with the SigV4 headers added
  const response = await fetch(signed);
  await response.json();
};

Data Masking

The new @aws-lambda-powertools/data-masking package lets you encrypt, decrypt, or irreversibly erase sensitive fields within nested event data, using the AWS Encryption SDK and envelope encryption with AWS KMS for encrypt/decrypt operations.

import { DataMasking } from '@aws-lambda-powertools/data-masking';

const masker = new DataMasking();

export const handler = async (event: { body: Record<string, unknown> }) => {
  const data = event.body;

  return masker.erase(data, {
    fields: ['email', 'address.street', 'company_address'],
  });
};

Custom masking rules — partial masking via regex, dynamic-length masks, or a fixed replacement string — are also supported for cases where the default ***** placeholder isn't enough.

Lambda Managed Instances concurrency fixes

Under Lambda Managed Instances, multiple invocations can be multiplexed into the same execution environment. Logger and Tracer previously stored per-invocation state (the Lambda context, the active X-Ray segment, and middleware-scoped subsegments) in shared instance variables rather than scoping it per invocation, so concurrent invocations could stomp on each other's state:

  • Logger could emit log lines with the wrong function_request_id, tenant_id, and cold_start — the values from whichever invocation last called addContext().
  • Tracer could attach putAnnotation/putMetadata calls, captured responses, and captured errors to the wrong invocation's trace, and the captureLambdaHandler middy middleware could close the wrong subsegment or leave one open.

Both utilities now scope this state per invocation using the Lambda Invoke Store, matching the approach already used by Metrics and Batch, so trace and log data stay correctly attributed to the invocation that produced them.

Automatic metric flushing with using

Metrics now implements Disposable, so on Node.js 24+ you can flush stored metrics automatically when a using binding leaves scope — including when an exception is thrown — without a manual try/finally block or the middleware/decorator.

import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';

const metrics = new Metrics({
  namespace: 'serverlessAirline',
  serviceName: 'orders',
});

export const handler = async (): Promise<void> => {
  using _ = metrics.addMetric('successfulBooking', MetricUnit.Count, 10);
  // metrics are flushed automatically when the scope exits, including on errors
};

Changes

  • chore(testing): use stackEventPollingInterval option, drop CDK patch (#5447) by @svozza
  • fix(tracer): isolate active segment per invocation under LMI concurrency (#5446) by @svozza
  • fix(idempotency): recompute key prefix from base on each configure call (#5442) by @dreamorosi
  • fix(tracer): scope middy middleware segments per invocation (#5444) by @vishwakt
  • feat(parser): add errorHandler option for inline parse error handling (#5352) by @Zelys-DFKH
  • refactor(logger): remove unsafe context cast in createChild (#5443) by @dreamorosi
  • feat(idempotency): warn when persistence layer reconfiguration is ignored (#5422) by @dreamorosi
  • chore(skills): make create-issue checkbox handling template-driven (#5439) by @svozza
  • fix(logger): scope lambda context per invocation under LMI concurrency (#5430) by @svozza
  • docs(event-handler): mention HTTP event handler in package README (#5432) by @svozza
  • docs(event-handler): note Bedrock Agents maintenance mode (#5425) by @dreamorosi
  • refactor(commons): extract shared isRunningInLambda helper (#5424) by @dreamorosi
  • refactor(testing): remove withResolvers polyfill, use native method (#5427) by @dreamorosi
  • chore(deps): bump transitive protobufjs from 7.5.8 to 7.6.5 (#5421) by @dreamorosi
  • feat(signer): add SigV4 request signing utility (#5344) by @dreamorosi
  • docs(idempotency): explain persistence layer reuse across multiple operations (#5419) by @dreamorosi
  • docs: document npm package name reservation in maintainers playbook (#5418) by @dreamorosi
  • chore(governance): add shared agent skills for creating issues and PRs (#5407) by @svozza
  • ci: slow CDK stack-event polling to avoid CFN throttling (#5405) by @svozza
  • chore(tests): prevent sentinel key collision in data-masking property test (#5392) by @svozza
  • ci(layers): update SSM latest parameter on release (#5369) by @dreamorosi
  • chore(maintenance): remove DOM lib, use undici-types for fetch types (#5351) by @svozza
  • fix(event-handler): preserve original string for invalid Bedrock Agent number params (#5363) by @kimnamu
  • feat(metrics): add Disposable support for automatic flushing via using (#5349) by @svozza
  • feat(data-masking): add Data Masking utility (#5143) by @svozza
  • feat(parameters): add throwOnMissing option to fail fast on missing values (#5343) by @dreamorosi
  • chore(ci): type-check examples/snippets and fix uncovered errors (#5348) by @dreamorosi
  • refactor(event-handler): extract shared IP-extraction util for HTTP middleware (#5346) by @dreamorosi
  • feat(event-handler): add HTTP request/response data to tracer subsegment (#5338) by @dreamorosi
  • build(internal): add test compilation check to package builds (#5336) by @dreamorosi
  • feat(event-handler): warn when AppSync Events payload exceeds 240 KB per-event limit (#5339) by @dreamorosi
  • chore: approve install scripts for npm v12 allowScripts (#5340) by @svozza
  • chore: clear npm audit on aws-cdk-lib transitive dep (#5328) by @dreamorosi
  • ci(maintenance): remove PR/branch checkout input from Run e2e Tests workflow (#5326) by @dreamorosi
  • test(event-handler): fix stale httpRouter e2e trailing-slash test (#5314) by @svozza
  • fix(event-handler): avoid runtime import of metrics package in HTTP metrics middleware (#5310) by @vishwakt
  • chore(commons): guard UA string against duplicate PTEnv suffix (#5311) by @svozza
  • fix(event-handler): correct InvalidHttpMethodError name (#5254) by @svozza
  • chore(idempotency): bump @aws/durable-execution-sdk-js to ^1.1.6 (#5298) by @svozza
  • fix(event-handler): normalize trailing slashes in HTTP Router prefix joining (#5255) by @svozza
  • fix(commons): clear LRUCache pointers on eviction of last item (#5295) by @vishwakt
  • chore(deps): bump aws-cdk and aws-cdk-lib to clear fast-uri advisories (#5292) by @svozza
  • fix(metrics): detect key collisions between dimensions, metrics, and metadata (#5240) by @Zelys-DFKH

🔧 Maintenance

Read more

v2.33.1

Choose a tag to compare

@github-actions github-actions released this 25 May 10:27
a3d3147

Summary

This release is mainly composed of bug fixes across the HTTP event handler, Metrics, Logger, and Parser utilities, along with the removal of Node.js 20 support now that the runtime has reached end-of-life on AWS Lambda.

In the HTTP event handler, we have fixed response header corruption where multi-attribute headers like Set-Cookie (with Expires dates) and other comma-containing values were being incorrectly split into multiple headers. The HTTP event handler also now correctly preserves PATCH request bodies on ALB events and returns the proper 204 response for CORS preflight requests that omit the Access-Control-Request-Headers header.

In Metrics, dimension limits are now enforced per-array rather than across the merged set, preventing CloudWatch EMF rejections when default and request-scoped dimensions overlap. Logger now flushes the log buffer when critical() is called with flushOnErrorLog enabled, matching the behaviour of error().

Important

Node.js 20 is no longer supported. Node.js 20 reached end-of-life on AWS Lambda, so this release drops support for it. If you are still on Node.js 20, we recommend upgrading to Node.js 22 before updating Powertools.

⭐ Congratulations to @vishwakt and @nanookclaw for their first PRs merged in the project 🎉

Changes

  • chore(deps): fix npm audit vulnerabilities (#5269) by @svozza
  • fix(event-handler): allow cors preflight without request headers (#5267) by @vishwakt
  • fix(event-handler): preserve ALB PATCH bodies (#5259) by @nanookclaw
  • fix(event-handler): restrict v1/alb comma header splitting to an allowlist (#5257) by @vishwakt
  • fix(parser): cognito validationData may be null (#5250) by @bdellegrazie
  • fix(metrics): enforce dimension limits per-array (#5229) by @vishwakt
  • improv(docs): fixed the docs to mention middy support for v7.x (#5238) by @sdangol
  • fix(metrics): account for all dimensions in setDefaultDimensions() li… (#5228) by @vishwakt
  • fix(logger): flush log buffer on critical() when flushOnErrorLog is e… (#5227) by @vishwakt
  • fix(metrics): clear state in publishStoredMetrics even when throwOnEmptyMetrics throws (#5213) by @svozza
  • chore: drop Node.js 20 support (#5218) by @svozza
  • fix(commons): prevent deepMerge from mutating source objects (#5202) by @svozza
  • fix(commons): correctly handle shared references in deepMerge (#5195) by @svozza
  • ci(maintenance): Remove release comment automation (#5193) by @dreamorosi
  • fix(logger): correctly serialize shared object references in JSON replacer (#5186) by @svozza

🔧 Maintenance

This release was made possible by the following contributors:

@bdellegrazie, @dependabot[bot], @dreamorosi, @github-actions[bot], @nanookclaw, @sdangol, @svozza, @vishwakt, dependabot[bot] and github-actions[bot]

v2.33.0

Choose a tag to compare

@github-actions github-actions released this 14 Apr 12:58
5765cc4

Summary

In this release, the HTTP event handler gains a new metrics middleware that lets you emit per-request latency, fault, and error metrics with a single line of configuration. The middleware automatically uses the matched route as a dimension and attaches request metadata like HTTP method, path, status code, and API Gateway request IDs.

We've also improved the parser package by exporting InferOutput from the public types entry point, resolving a TypeScript declaration emit error (TS2883) that affected consumers using safeParse mode — particularly those upgrading to TypeScript 6.

⭐ Congratulations to @yashar-new10 and @faberchri for their first PR merged in the project 🎉

Metrics Middleware

You can now use the Metrics utility with the HTTP event handler to automatically emit CloudWatch metrics for every request. The middleware:

  • Adds the matched route as a metric dimension (e.g., GET /users/:id)
  • Emits latency (Milliseconds), fault (Count), and error (Count) metrics
  • Attaches request metadata including httpMethod, path, statusCode, userAgent, and ipAddress
  • Adds API Gateway-specific metadata (apiGwRequestId, apiGwApiId) when available
  • Uses NOT_FOUND as the route dimension when no route matches, preventing dimension explosion
import { Router } from '@aws-lambda-powertools/event-handler/http';
import { metrics as metricsMiddleware } from '@aws-lambda-powertools/event-handler/http/middleware/metrics';
import { Metrics } from '@aws-lambda-powertools/metrics;
import type { Context } from 'aws-lambda';

const metrics = new Metrics({ namespace: 'my-app', serviceName: 'my-service' });
const app = new Router();

app.use(metricsMiddleware(metrics));

app.get('/users/:id', async ({ params }) => {
  return { id: params.id, name: 'Jane' };
});

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

Changes

  • improv(parser): export InferOutput from public types entry point (#5175) by @yashar-new10
  • chore(deps): add esbuild as explicit devDependency (#5173) by @sdangol
  • chore: temporarily remove Bahrain (me-south-1) region from layer publishing (#5169) by @svozza
  • docs(commons): fix isStrictEqual and areArraysEqual JSDoc array comparison description (#5165) by @Zelys-DFKH
  • docs: fix dependencies & broken references (#5156) by @dreamorosi
  • docs: fix markdown table format (#5153) by @dothomson
  • style: remove useAwait linting rule (#5146) by @dreamorosi
  • docs(event-handler): update custom middleware example to use Store API (#5145) by @svozza
  • fix(commons): don't overwrite existing value with undefined in deepMerge (#5141) by @faberchri
  • fix(event-handler): http response body validation typings (#5125) by @nateiler
  • feat(event-handler): add metrics middleware for HTTP routes (#5086) by @svozza
  • fix: update middy types to be aligned with 7.1.2 update (#5100) by @willfarrell
  • fix(commons): rename AvailabilityZoneId to AvailabilityZoneID in docs and tests (#5118) by @svozza

🔧 Maintenance

This release was made possible by the following contributors:

@Zelys-DFKH, @dependabot[bot], @dothomson, @dreamorosi, @faberchri, @github-actions[bot], @nateiler, @sdangol, @svozza, @willfarrell, @yashar-new10, dependabot[bot] and github-actions[bot]

v2.32.0

Choose a tag to compare

@github-actions github-actions released this 20 Mar 16:13
0abf2f0

Summary

In this release, we are pleased to announce a new utility for interacting with the Lambda Metadata Service in the commons package, allowing you to easily retrieve information about the Lambda function, such as the Availability Zone ID.

In the HTTP event handler, we have delivered two much requested features: a type-safe Store API, letting you share state between middleware and route handlers with full type safety, and request and response validation, so you can enforce data contracts at your API boundary, eliminating manual parsing and type assertion code.

We've also fixed a bug where the Kafka consumer would throw when processing tombstone events with undefined values.

⭐ Congratulations to @haslers for their first PR merged in the project 🎉

Lambda Metadata Service

A new getMetadata() utility in the commons package fetches metadata from the AWS Lambda Metadata endpoint. The utility automatically returns an empty object outside of Lambda, so your code works seamlessly in local development and testing.

import { getMetadata } from '@aws-lambda-powertools/commons/utils/metadata';
import { Logger } from '@aws-lambda-powertools/logger';

const logger = new Logger({ serviceName: 'serverlessAirline' });
const metadata = await getMetadata();

export const handler = async () => {
  const { AvailabilityZoneID: azId } = metadata;
  logger.appendKeys({ azId });
};

Type-safe Store API

The HTTP event handler now includes a Store API that provides type-safe, scoped state management for route handlers with two built-in storage scopes:

  • Request store — per-invocation state (set in middleware, read in handlers). Cleared automatically between requests.
  • Shared store — router-scoped state (set at cold start, read everywhere). Persists across invocations.
import { Router } from '@aws-lambda-powertools/event-handler/http';
import type { Context } from 'aws-lambda';

type AppEnv = {
  store: {
    request: { userId: string; isAdmin: boolean };
    shared: { db: { query: (sql: string) => Promise<unknown> } };
  };
};

const app = new Router<AppEnv>();

app.shared.set('db', createDbClient());

app.use(async ({ reqCtx, next }) => {
  const auth = reqCtx.req.headers.get('Authorization') ?? '';
  const { sub, isAdmin } = jwt.verify(auth.replace('Bearer ', ''), 'secret');
  reqCtx.set('userId', sub);
  reqCtx.set('isAdmin', isAdmin);
  await next();
});

app.get('/profile', async (reqCtx) => {
  const userId = reqCtx.get('userId');   // typed as string
  const db = reqCtx.shared.get('db');    // typed as { query: ... }
  if (!userId || !db) return { error: 'not ready' };
  return { userId };
});

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

Validation Middleware

The new validation feature validates validates request and response data against Standard Schema v1 schemas — a vendor-neutral interface supported by Zod, Valibot, ArkType, and other popular libraries.

You can validate any combination of request body, headers, path parameters, and query parameters. Request validation errors return a structured 422 Unprocessable Entity response, and response validation errors return 500 Internal Server Error. TypeScript infers the handler's context type from your schema config — only validated fields are accessible, catching mismatches at compile time.

import { Router } from '@aws-lambda-powertools/event-handler/http';
import type { Context } from 'aws-lambda';
import { z } from 'zod';

const app = new Router();

const createTodoSchema = z.object({ title: z.string() });

const todoResponseSchema = z.object({
  id: z.string(),
  title: z.string(),
  completed: z.boolean(),
});

app.post(
  '/todos',
  (reqCtx) => {
    const { title } = reqCtx.valid.req.body; // fully typed
    return { id: '123', title, completed: false };
  },
  {
    validation: {
      req: { body: createTodoSchema },
      res: { body: todoResponseSchema }, // runtime check on the response
    },
  }
);

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

Changes

  • fix(commons): rename AvailabilityZoneId to AvailabilityZoneID in docs and tests (#5118) by @svozza
  • chore(ci): temporarily disable me-central-1 deployments (#5111) by @svozza
  • feat(commons): add Lambda Metadata Service support (#5109) by @svozza
  • revert: feat(commons): add Lambda Metadata Service support (#5106) (#5107) by @svozza
  • feat(commons): add Lambda Metadata Service support (#5106) by @svozza
  • feat(event-handler): add type-safe Store API for request and shared state (#5081) by @svozza
  • chore(deps): regenerate package-lock.json to clear stale Dependabot alerts (#5075) by @dreamorosi
  • fix(event-handler): add overloads to route() for typed validation context (#5052) by @svozza
  • chore: run linting on packages, run npm audit fix manually, address SonarCloud (#5046) by @dreamorosi
  • fix(event-handler): default error handler returns a web Response correctly (#5024) by @nateiler
  • fix(kafka): handle tombstone events without value (#5017) by @haslers
  • ci: use ts extension in layer CDK stack imports (#5010) by @svozza
  • ci: fix layer import in CDK stack (#5009) by @dreamorosi

📜 Documentation updates

  • feat(event-handler): add validation support for REST router (#4736) by @sdangol

🔧 Maintenance

Read more

v2.31.0

Choose a tag to compare

@github-actions github-actions released this 12 Feb 13:13
54d1fa3

Summary

In this release we are pleased to announce Tracer middleware for the HTTP event handler, which allows users to enable distributed tracing for their HTTP routes with minimal boilerplate code.

In addition, the metric utility now supports a fluent interface, allowing you to chain multiple methods in a single statement.

We have also fixed a bug in the HTTP event handler that caused parameterized headers to be handled incorrectly.

⭐ Special thanks to @nateiler and @dothomson for their first PR merged in the project, and to @arnabrahman! for another great contribution 🎉

Tracer Middleware

You can now use the Tracer utility with the HTTP event handler to gain observability over your routes. The middleware:

  • Creates a subsegment for each HTTP route with the format METHOD /path (e.g., GET /users)
  • Adds ColdStart and Service annotations
  • Optionally captures JSON response bodies as metadata
  • Captures errors as metadata when exceptions occur
import { Router } from '@aws-lambda-powertools/event-handler/http';
import { tracer as tracerMiddleware } from '@aws-lambda-powertools/event-handler/http/middleware/tracer';
import { Tracer } from '@aws-lambda-powertools/tracer';
import type { Context } from 'aws-lambda';

const tracer = new Tracer({ serviceName: 'my-api' });
const app = new Router();

app.get(
  '/users/cards',
  [tracerMiddleware(tracer, { captureResponse: false })],
  ({ params }) => {
    return { id: params.id, secret: 'sensitive-data' };
  }
);

export const handler = async (event: unknown, context: Context) =>
  app.resolve(event, context);

Metrics Fluent Interface

All mutation methods (with the exception of clear*) now return the metric instance that was mutated, allowing you to chain multiple metrics operations in a single statement.

import { Metrics} from '@aws-lambda-powertools/metrics';

const metrics = new Metrics();

metrics
    .addDimension('environment', 'prod')
    .addDimension('commit', '1234')
    .addMetric('test1', MetricUnit.Count, 1);
    .addMetric('test2', MetricUnit.Count, 1);

Changes

📜 Documentation updates

🔧 Maintenance

Read more

v2.30.2

Choose a tag to compare

@github-actions github-actions released this 12 Jan 12:31
48a557d

Summary

In this release we have added Middy v7 middleware compatibility which enables developers using Middy to use Durable functions, Tenant isolation mode, and multi-concurrency on Lambda Managed Instances.

We have also now added a new tenantId property by default for tenant identification in all log entries, making it easier to filter and trace logs across different tenants in your Lambda functions.

⭐ Special thanks to @coderbyheart for their first PR merged in the project 🎉

Changes

📜 Documentation updates

  • chore(deps): bump urllib3 from 2.6.0 to 2.6.3 in /docs (#4927) by @dependabot[bot]
  • improv(docs): added a note for customers migrating from BatchProcessorSync to BatchProcessor (#4926) by @sdangol
  • improv(docs): updated the Maintainer's Playbook with the updated CI process (#4922) by @sdangol

🔧 Maintenance

  • chore(batch): remove invoke store global namespace workaround (#4932) by @svozza
  • chore(deps): bump urllib3 from 2.6.0 to 2.6.3 in /docs (#4927) by @dependabot[bot]
  • feat: remove baseUrl from TypeScript configurations for future compiler compatibility (#4925) by @dreamorosi
  • improv(docs): updated the Maintainer's Playbook with the updated CI process (#4922) by @sdangol

This release was made possible by the following contributors:

@coderbyheart, @dependabot[bot], @dreamorosi, @github-actions[bot], @kawaaaas, @sdangol, @svozza, dependabot[bot] and github-actions[bot]

v2.30.1

Choose a tag to compare

@github-actions github-actions released this 06 Jan 16:31
1ec1c03

Summary

In this release we have removed lodash.merge , allowing users to simplify their bundling process as special handling of this CommonJS only dependency is no longer required.

⭐ Special thanks to @jaimellamasi for their work on the lodash migration! 🎉

Changes

  • improv(ci): Added environment suffix to prevent artefact name conflict (#4921) by @sdangol
  • fix(logger): improve e2e test resilience by grouping logs by level (#4909) by @dreamorosi
  • chore(ci): prevent parameter injection in make-version workflow (#4900) by @dreamorosi
  • chore(ci): harden workflow permissions for security compliance (#4898) by @dreamorosi
  • improv(ci): fixed the Make Release workflow (#4867) by @sdangol
  • improv(ci): automated the Gamma/Prod deployment to China/GovCloud regions (#4864) by @sdangol

📜 Documentation updates

🔧 Maintenance

This release was made possible by the following contributors:

@dependabot[bot], @dreamorosi, @github-actions[bot], @jaimellamasi, @sdangol, dependabot[bot] and github-actions[bot]

v2.30.0

Choose a tag to compare

@github-actions github-actions released this 11 Dec 17:23
dd5395b

Summary

We're excited to announce AWS Lambda durable function support in Powertools for AWS Lambda TypeScript. This allows you to leverage AWS Lambda's new durable execution capabilities while taking the advantage of features such as maintaining idempotency guarantees, making it easier to build reliable serverless workflows that span multiple invocations.

AWS Lambda durable functions allow you to simplify building multi-step applications and AI workflows. These functions automatically checkpoint progress, suspend execution for up to one year during long-running tasks, and recover from failures without the need to manage additional infrastructure.

Note

Lambda function handlers using MiddyJS or Class method decorators aren’t compatible with Durable Function handlers at this time.
Tracking issues: MiddyJS middyjs/middy#1531
Class Decorator #4832

This release also includes some bug fixes and a documentation improvement with the help of the community.

⭐ Congratulations to @jinxiao and @dwandro for their first PR merged in the project 🎉

Changes

  • fix(logger): merged temp keys with same keys when appending to the logger (#4840) by @sdangol
  • fix(idempotency): Update durableExecutionMode string (#4837) by @ConnorKirk
  • feat(idempotency): Allow durable function to replay (#4834) by @ConnorKirk
  • fix(event-handler): threshold limit for compression not respected when content-length not set (#4827) by @svozza
  • feat(parser): fix DynamoDBStreamChangeRecordSchema.dynamodb type (#4817) by @benthorner

📜 Documentation updates

🔧 Maintenance

This release was made possible by the following contributors:

@ConnorKirk, @benthorner, @dependabot[bot], @dwandro, @github-actions[bot], @jinxiao, @sdangol, @svozza, dependabot[bot] and github-actions[bot]