Skip to content

Bug: event-handler HTTP Router prefix joining drops trailing slash and produces double slashes #5252

@svozza

Description

@svozza

Expected Behavior

When constructing new Router({ prefix: '/api' }) and registering a root route with app.get('/', handler), the route should be reachable at the prefix path (/api and/or /api/). When the prefix accidentally ends with /, joining a child path should not produce a double slash.

Current Behavior

resolvePrefixedPath (packages/event-handler/src/http/utils.ts:334-346) ends with:

return `${prefix}${path}`.replace(/\/$/, '') as Path;

Two concrete failures:

  1. resolvePrefixedPath('/', '/api') returns '/api' — the trailing slash is stripped. A handler registered at / under /api is unreachable from /api/; the request resolves to 404.
  2. resolvePrefixedPath('/users', '/api/') returns '/api//users' — a literal double slash. Incoming requests to /api/users don't match the registered route id.

Code snippet

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

const app = new Router({ prefix: '/api' });
app.get('/', () => ({ root: true }));

// Request to /api/ → 404 Not Found (expected: 200 with { root: true })

const app2 = new Router({ prefix: '/api/' });
app2.get('/users', () => ({ users: [] }));

// Internally registers GET:/api//users; request to /api/users → 404

Steps to Reproduce

  1. Construct a Router with prefix: '/api' and register a handler at '/'.
  2. Resolve a request for /api/.
  3. Observe statusCode: 404.
  4. Repeat with prefix: '/api/' and path: '/users'; observe the registered route id contains //.
  5. Or run the failing test: npx vitest --run tests/unit/http/bugHunt.test.ts -t "Bug 5" from packages/event-handler/.

Possible Solution

No response

Powertools for AWS Lambda (TypeScript) version

latest

AWS Lambda function runtime

22.x

Packaging format used

npm

Execution logs

(not applicable — bug is reproducible from a unit test)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingconfirmedThe scope is clear, ready for implementation

    Type

    No type

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions