Skip to content

getSession(req) fails in middleware: req instanceof NextRequest returns false #2253

@arklanq-patronus

Description

@arklanq-patronus

Checklist

Description

When calling getSession(req) from inside a Next.js Middleware, the following check inside the library fails:

if (req instanceof NextRequest) {

// src/server/client.ts:362
if (req instanceof NextRequest) {
  ...
}

This is because in the Middleware context, request object is not an instance of NextRequest, but rather NextRequestHint, which is structurally similar but does not inherit from NextRequest. As a result, the condition returns false, and the wrong branch of logic is executed (falling back to createRequestCookies(req) which expects a different shape).

req is of type NextRequest, but it’s not an instance of NextRequest. Its prototype is NextRequestHint.

As a result, if I invoke getSession(req), providing req: NextRequest, I get an error:

 ⨯ TypeError: Headers.append: "append(name, value) {
        webidl.brandCheck(this, _Headers);
        webidl.argumentLengthCheck(arguments, 2, "Headers.append");
        const prefix = "Headers.append";
        name = webidl.converters.ByteString(name, prefix, "name");
        value = webidl.converters.ByteString(value, prefix, "value");
        return appendHeader(this, name, value);
      }" is an invalid header value.
    at refreshAccessTokenEndpointHandler (src/server__new/auth/providers/auth0/refresh-access-token/refresh-access-token-endpoint-handler.ts:36:35)
    at auth0RouterMiddleware (src/server__new/auth/providers/auth0/router-middleware.ts:40:47)

You need a better way to distinguish between a middleware usage and pages router usage than simple instanceof check (which doesn't work):

    async getSession(req) {
        if (req) {
            // middleware usage
            if (req instanceof NextRequest) {
                return this.sessionStore.get(req.cookies);
            }
            // pages router usage
            return this.sessionStore.get(this.createRequestCookies(req));
        }
        // app router usage: Server Components, Server Actions, Route Handlers
        return this.sessionStore.get(await cookies());
    }

Reproduction

middleware.ts

// imports, config

export async function middleware(request: NextRequest) {
  const authRes = await auth0.middleware(request);

  if (request.nextUrl.pathname.startsWith("/auth")) {
    return authRes;
  }

  const session = await auth0.getSession(request);

  if (!session) {
    // user is not authenticated, redirect to login page
    return NextResponse.redirect(
      new URL("/auth/login", request.nextUrl.origin)
    );
  }

  // the headers from the auth middleware should always be returned
  return authRes;
}

Additional context

getAccessToken method is affected as well because it utilizes getSession under the hood.

Related:

nextjs-auth0 version

4.9.0

Next.js version

15.4.2-canary.26

Node.js version

v22.15.0

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions