Skip to content

aws-lambda preset: awsRequest() returns a new Request object without runtime metadata, and uses wrong property name (aws instead of awsLambda) #4287

@fossamagna

Description

@fossamagna

Environment

Node.js: v24.14.0
Nitro: 3.0.260429-beta
Nitro preset: aws-lambda
Use case: TanStack Start on AWS Lambda with @aws-lambda-powertools/logger

vite.config.ts

import { devtools } from '@tanstack/devtools-vite'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'

export default defineConfig(({ command }) => ({
  plugins: [
    devtools(),
    tsconfigPaths({ projects: ['./tsconfig.json'] }),
    tanstackStart({router: {routeFileIgnorePattern: ".*\\.test\\.tsx?$"}}),
    nitro({ preset: 'aws_lambda' }),
    viteReact()
  ],
  ssr: {
    noExternal: command === 'build' ? true : undefined,
  },
}))

Reproduction

server.ts:

fetch(request) {
  const runtime = (request as ServerRequest).runtime;
  if (runtime?.name === "aws-lambda" && runtime.awsLambda) { // always `runtime.awsLambda` is `undefined`
    powertoolsLogger.addContext(runtime.awsLambda.context);
    powertoolsLogger.logEventIfEnabled(runtime.awsLambda.event);
  }
  return handler.fetch(request);
}

Describe the bug

There are two bugs in src/presets/aws-lambda/runtime/_utils.ts in the awsRequest() function that prevent accessing Lambda's event and context from a request handler.

Bug 1: Discards the Request object with runtime metadata

The function creates a ServerRequest (req), sets req.runtime.aws, but then returns a brand-new Request object — discarding all the runtime metadata that was just set.

const req = new Request(url, { method, headers, body }) as ServerRequest;

req.runtime ??= { name: "aws-lambda" };
req.runtime.aws ??= { event, context } as any;

return new Request(url, { method, headers, body }); // ← returns a different object; runtime is lost

Bug 2: Wrong property name (aws instead of awsLambda)

Even if the first bug were fixed, the runtime property is set as req.runtime.aws, but srvx's ServerRequest type exposes the AWS context under runtime.awsLambda. Accessing runtime.awsLambda therefore returns undefined.

Expected Behavior

The following pattern should work to access Lambda's event and context from a request handler:

fetch(request) {
  const runtime = (request as ServerRequest).runtime;
  if (runtime?.name === "aws-lambda" && runtime.awsLambda) {
    powertoolsLogger.addContext(runtime.awsLambda.context);
    powertoolsLogger.logEventIfEnabled(runtime.awsLambda.event);
  }
  return handler.fetch(request);
}

Suggested Fix

export function awsRequest(
  event: APIGatewayProxyEvent | APIGatewayProxyEventV2,
  context: unknown
): ServerRequest {
  const method = awsEventMethod(event);
  const url = awsEventURL(event);
  const headers = awsEventHeaders(event);
  const body = awsEventBody(event);

  const req = new Request(url, { method, headers, body }) as ServerRequest;

  // srvx compatibility
  req.runtime ??= { name: "aws-lambda" };
  req.runtime.awsLambda ??= { event, context } as any; // fix: use awsLambda, not aws

  return req; // fix: return the same object with runtime set
}

Additional context

No response

Logs

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions