middlewareHandler is not a function

Hello! I used new nodeMiddleware with canary build. Worked ok, I made some production deployments with it. After I created preview deployment it started to error in every middleware invocation with error

TypeError: middlewareHandler is not a function
    at /var/task/___next_launcher.cjs:116:30
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)
    at withNextRequestContext (/var/task/___next_launcher.cjs:30:18)
    ...

I would expect it not to crash, Locally my builds doing great

I have

  experimental: {
    nodeMiddleware: true,
  },

and next.js version 15.3.0-canary.36

Next.js

1 Like

Hey @kirill-x. There’s not enough info here for me to be sure of what’s causing the error. I wrote another post with some suggestions for what details are helpful to include.

Please take a look and then add whatever you can here to help the rest of us see what’s going wrong :folded_hands:

1 Like

Hey! Im not sure what details are needed for this issue.
Here is error that is displayed instead of my preview website on the routes, that are triggering middleware

500: INTERNAL_SERVER_ERROR
Code: MIDDLEWARE_INVOCATION_FAILED
ID: arn1::2jvf2-1744869020703-69d318d20d0b

This is the full stacktrace from logs on vercel dashboard

TypeError: middlewareHandler is not a function
    at /var/task/___next_launcher.cjs:116:30
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)
    at withNextRequestContext (/var/task/___next_launcher.cjs:30:18)
    at Object.serve [as handlerWeb] (/var/task/___next_launcher.cjs:113:18)
    at Object.handler (/opt/rust/nodejs.js:2:14544)
    at Server.<anonymous> (/opt/rust/nodejs.js:2:1716)
    at /opt/rust/nodejs.js:16:6144
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)
    at /opt/rust/nodejs.js:16:6132
    at AsyncLocalStorage.run (node:internal/async_local_storage/async_hooks:91:14)

this is deployment ID

dpl_9MXV9H295nB8ZRonuNrUNqnmQKLc

What else could I share to help debug this issue?

Thanks for sharing the error info and deployment id. From what I can see in the logs, it looks like that build used an older Next.js canary version. Does the TypeError still happen if you switch to either latest or canary to make sure the most recent updates are included?

I had in package.json exact version that currently works fine in production deployment.
I updated version in preview branch to canary now, error is still there.

Are you able to share a minimal reproducible example or code snippets to show the middleware and routes triggering it?

Hi! I’m also using next js canary version and got the same error. May I ask for updates? Have you figure it out?

Never mind. I figured it out, hahaha. I moved my middleware.ts file inside the app folder. Previously, it was located in the root directory, and there was no problem with that locally, but Vercel couldn’t detect it. It seems Vercel can only detect it if it’s inside the app folder. That solved it for me.

I dont think I can make an example. I merged my branch to main and now problem is gone. Not sure what it was by it is related to how vercel treat barnch deploymnets

The main difference between preview deployments and production is whether NODE_ENV=production or not by default

You can try setting that explicitly in your environment variables to override and see if that helps you reproduce the scenario

If it is an issue that only breaks when in non-production, then double check whether your Next modules are in regular “dependencies” or “devDependencies”

1 Like

now this error randomly appeared in production branch after last deployment. It now block release version of the website

Project ID prj_uLlosTk50TCeFeq8nlxbCBAJnDeK

Getting exact same error on 10.4.0 canary 9

I had to stop using nodejs as middleware because of this error. It seem random and untracable as it only happens in vercel cloud platform

1 Like

Still an issue on. Any update on this?

TypeError: middlewareHandler is not a function
    at /var/task/___next_launcher.cjs:116:30
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at withNextRequestContext (/var/task/___next_launcher.cjs:30:18)
    at Object.serve [as handlerWeb] (/var/task/___next_launcher.cjs:113:18)
    at Object.handler (/opt/rust/nodejs.js:2:14544)
    at Server.<anonymous> (/opt/rust/nodejs.js:2:1716)
    at /opt/rust/nodejs.js:16:6144
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at /opt/rust/nodejs.js:16:6132
    at AsyncLocalStorage.run (node:async_hooks:346:14)

Getting the same issue. it’s related to node middleware.

I have the same issue relates to node middleware

Exact same issue with nodejs middleware. Someone found a temporary fix ?

I hit this issue; we use turborepo and this was happening because the package.json in the root directory (for turborepo) was using a different version of next (non-canary)

1 Like

same issue :

TypeError: middlewareHandler is not a function
    at /var/task/___next_launcher.cjs:116:30
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at withNextRequestContext (/var/task/___next_launcher.cjs:30:18)
    at Object.serve [as handlerWeb] (/var/task/___next_launcher.cjs:113:18)
    at Object.handler (/opt/rust/nodejs.js:2:14518)
    at Server.<anonymous> (/opt/rust/nodejs.js:2:1736)
    at /opt/rust/nodejs.js:16:7231
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at /opt/rust/nodejs.js:16:7219
    at AsyncLocalStorage.run (node:async_hooks:346:14)
Node.js process exited with exit status: 1. The logs above can help with debugging the issue.

i just merged a new branch and now i cant use the app hhhh so it was working before reverting back the merge didnt fix it so its not the code hmmm

Got hit by this. Middleware code:

import { NextRequest, NextResponse } from "next/server";
import { headers } from "next/headers";

import { AUTH_ROUTE_BASE, USER_ROUTE_BASE } from "@/constants/app";
import { auth } from "@/authentication";
import { getRouteContext } from "@/utils";

export async function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;
  const { isDealerRoute, isUserRoute, isLoginOrSignupRoute, isAdminRoute } =
    getRouteContext(pathname);

  const session = await auth.api.getSession({
    headers: await headers(),
  });

  if (!session) {
    if (isLoginOrSignupRoute) {
      return NextResponse.next();
    }
    if (isUserRoute) {
      return NextResponse.next();
    }
    // Redirect unauthenticated users to login
    return NextResponse.redirect(
      new URL(`${AUTH_ROUTE_BASE}/login`, request.url),
    );
  }

  if (session && isLoginOrSignupRoute) {
    // Redirect authenticated users away from signup/login pages
    return NextResponse.redirect(new URL(USER_ROUTE_BASE, request.url));
  }

  const hasDealerPermissions = await auth.api.userHasPermission({
    headers: await headers(),
    body: {
      permissions: {},
      role: "dealer",
    },
  });
  const hasAdminPermissions = await auth.api.userHasPermission({
    headers: await headers(),
    body: {
      permissions: {},
      role: "admin",
    },
  });

  if (isDealerRoute && (!hasDealerPermissions || !hasAdminPermissions)) {
    // Redirect if user is not authorized for dealer routes
    return NextResponse.redirect(new URL(USER_ROUTE_BASE, request.url));
  }

  if (isAdminRoute && !hasAdminPermissions) {
    // Redirect if user is not authorized for admin routes
    return NextResponse.redirect(new URL(USER_ROUTE_BASE, request.url));
  }

  return NextResponse.next();
}

export const config = {
  runtime: "nodejs",
  matcher: [
    "/((?!api|_next/static|_next/image|favicon.ico|auth/forgot-password|auth/reset-password).*)",
  ],
};