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
    No fields configured for issues without a type.

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions