Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next.js TypeError: Cannot read properties of undefined (reading 'bind') - caused by middleware.ts #56368

Open
1 task done
mstys opened this issue Oct 3, 2023 · 44 comments · May be fixed by #58704
Open
1 task done
Labels
linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@mstys
Copy link

mstys commented Oct 3, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:21:56 PDT 2023; root:xnu-8796.141.3~6/RELEASE_X86_64
Binaries:
  Node: 16.13.1
  npm: 8.19.2
  Yarn: 1.22.11
  pnpm: N/A
Relevant Packages:
  next: 13.5.4
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: N/A
Next.js Config:
  output: standalone

Which example does this report relate to?

https://github.com/vercel/next.js/blob/canary/examples/with-docker/README.md

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Describe the Bug

I getting following error on run next app after npm run build

(node:50480) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 ⚠ "next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.
  ▲ Next.js 13.5.4
  - Local:        http://localhost:3000

 ✓ Ready in 257ms
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/Users/michal.stys/OwnProjects/next13-test/node_modules/next/dist/server/base-server.js:389:50)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/Users/michal.stys/OwnProjects/next13-test/node_modules/next/dist/server/base-server.js:389:50)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

My middleware.ts from next.js docs.

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

const PUBLIC_FILE = /\.(.*)$/;

export async function middleware(req: NextRequest) {
  if (
    req.nextUrl.pathname.startsWith("/_next") ||
    req.nextUrl.pathname.includes("/api/") ||
    PUBLIC_FILE.test(req.nextUrl.pathname)
  ) {
    return;
  }

  if (req.nextUrl.locale === "default") {
    const locale = "en";
    return NextResponse.redirect(
      new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url)
    );
  }
}

PS. all works perfect without this middleware

Expected Behavior

Type error doesn't exists if using middleware.ts

To Reproduce

npx create-next-app --example with-docker nextjs-docker

// add middleware.ts added above

npm run build
npm start

NEXT-1739

@mstys mstys added the examples Issue was opened via the examples template. label Oct 3, 2023
@Phoenix-Alpha
Copy link

Phoenix-Alpha commented Oct 4, 2023

I also started to see this today after I upgrade Next.js to 13.5.4
image

@Lukacs5

This comment has been minimized.

@huozhi
Copy link
Member

huozhi commented Oct 4, 2023

There's a warning from the console, please run the standalone server instead

"next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.

@huozhi huozhi closed this as completed Oct 4, 2023
@mstys
Copy link
Author

mstys commented Oct 6, 2023

@huozhi it's warning not error. If you think that it works as expected it should throw error and not start.
"next start" does not work with "output: standalone" configuration. - means that standalone features are not running , not full Next app.

Moreover app works correctly without middleware.

@mstys
Copy link
Author

mstys commented Oct 6, 2023

@huozhi I tested it standalone mode as well before I created an issue, and got following error:

➜  next13-test git:(main) ✗ node .next/standalone/server.js
(node:94767) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
  ▲ Next.js 13.5.4
  - Local:        http://localhost:3000
  - Network:      http://0.0.0.0:3000

 ✓ Ready in 124ms
[
  {
    label: 'Your personal data',
    fields: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  }
]
{ list: [ { label: 'Your personal data', fields: [Array] } ] }
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/Users/michal.stys/OwnProjects/next13-test/.next/standalone/node_modules/next/dist/server/base-server.js:389:50)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/Users/michal.stys/OwnProjects/next13-test/.next/standalone/node_modules/next/dist/server/base-server.js:389:50)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

@Phoenix-Alpha
Copy link

@huozhi, this still exists - not sure why it's closed. This break features based on middleware and have other problem on Vercel, like sharp module not found even though it's added as dependency in package.json

@huozhi huozhi reopened this Oct 6, 2023
@huozhi
Copy link
Member

huozhi commented Oct 6, 2023

@mstys I couldn't repro that error with with-docker example and that middleware

➜  nextjs-docker git:(main) ✗ node ./.next/standalone/server.js
  ▲ Next.js 13.5.4
  - Local:        http://localhost:3000
  - Network:      http://0.0.0.0:3000

 ✓ Ready in 36ms

@huozhi
Copy link
Member

huozhi commented Oct 6, 2023

@Phoenix-Alpha sharp module not found sounds like a different issue, unrelated to this. Please open a new issue with reproduction

@mstys
Copy link
Author

mstys commented Oct 16, 2023

@huozhi you add middleware to project?

// middleware.ts

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

const PUBLIC_FILE = /\.(.*)$/;

export async function middleware(req: NextRequest) {
  if (
    req.nextUrl.pathname.startsWith("/_next") ||
    req.nextUrl.pathname.includes("/api/") ||
    PUBLIC_FILE.test(req.nextUrl.pathname)
  ) {
    return;
  }

  if (req.nextUrl.locale === "default") {
    const locale = "en";
    return NextResponse.redirect(
      new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url)
    );
  }
}

then try again

@huozhi
Copy link
Member

huozhi commented Oct 18, 2023

I did, I cannot repro it

@psd-coder
Copy link

psd-coder commented Oct 20, 2023

The bug is reproducible on Node.js 19 and above, with bare next app (obtained frompnpm create next-app) with the simplest middleware:

import { NextResponse } from "next/server";

export function middleware() {
  return NextResponse.next();
}

I got it on Node.js 20 (It will become the LTS on 24 of October) and with the unset output field in next.config.js

@jjojo
Copy link

jjojo commented Oct 26, 2023

I ran into this error as well. I could reproduce it only if I put the middleware.js file in root (I used the with-docker repo).
docker build -t nextjs-docker .

docker run -p 3000:3000 nextjs-docker
  ▲ Next.js 13.5.6
  - Local:        http://localhost:3000
  - Network:      http://0.0.0.0:3000

 ✓ Ready in 158ms
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/app/node_modules/next/dist/server/base-server.js:389:50)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
TypeError: Cannot read properties of undefined (reading 'bind')
    at NextNodeServer.handleRequestImpl (/app/node_modules/next/dist/server/base-server.js:389:50)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

However when I renamed the file from middleware.js to _middlewere.js the error dissapered. I tired this in my own project and the renaming indeed removes the error. I haven't ran all tests yet but I'll continue investigate this further tomorrow.

From the docs we can read:

For example, a Middleware at pages/about/_middleware.ts can move the logic to /middleware.ts in the root of your repository. Then, a conditional statement can be used to only run the Middleware when it matches the about/* path:

Is it possible it should say "/_middleware.(ts/js)" perhaps?

Here is a minimal reproduction of the behaviour:
nextjs-docker.zip

@kherona
Copy link

kherona commented Oct 31, 2023

I am running to the same issue on Node.js v18.15.0

@smartinio
Copy link

For me, the issue was that the middleware was being applied to my /ws (custom websocket) endpoint. I don't need any middleware on that endpoint, so adding this to middleware.ts fixes it:

export const config = {
  matcher: '/((?!ws$).*)', // match all paths except /ws
}

@spencerchang
Copy link

Same issue here, it will fix in the future right?
I saw a similar issue closed (issues/55802)

@ryanolee
Copy link

I think I might be know what is happening in most of the cases with this @spencerchang @mstys .
Did you have a browser tab open with the app left running in dev mode? (Given HMR tries to connect over websockets)

This error seems to occur when trying to connect to a standalone server in websocket mode with middleware enabled.

the handleRequestImpl method assumes that the passed res._res is always going to be a ServerResponse
image

but can be passed as a socket when calling the endpoint as a websocket:
image

(Try calling standalone server with new WebSocket ( "ws://127.0.0.1:3000" ) from a browser tab)

Think it might be worth excluding anything trying to connect over ws:// as a whole from being run as middleware @huozhi given the assumptions made in the current code? 🤔

AaronFriel added a commit to AaronFriel/next.js that referenced this issue Nov 20, 2023
Enables route handlers to receive and act on `Connection: Upgrade` requests, such as WebSockets,
when using the Node runtime. To enable this, the base http server has the `on('upgrade')` handler
removed. In this author's opinion, that handler is an anti-pattern as it makes it much more
difficult to handle middleware and other request lifecycle behavior.

By passing the raw request to the route handler and implementing a `NextResponse.upgrade()` response
value to opt out of additional processing that would write to the socket, the route handler can
handle an upgrade request itself.

Fixes vercel#58698 (feature request)
Fixes vercel#56368 (caused by next-ws / websocket middleware)
@huozhi huozhi added linear: next Confirmed issue that is tracked by the Next.js team. and removed examples Issue was opened via the examples template. labels Nov 27, 2023
AaronFriel added a commit to AaronFriel/next.js that referenced this issue Dec 1, 2023
Enables route handlers to receive and act on `Connection: Upgrade` requests, such as WebSockets,
when using the Node runtime. To enable this, the base http server has the `on('upgrade')` handler
removed. In this author's opinion, that handler is an anti-pattern as it makes it much more
difficult to handle middleware and other request lifecycle behavior.

By passing the raw request to the route handler and implementing a `NextResponse.upgrade()` response
value to opt out of additional processing that would write to the socket, the route handler can
handle an upgrade request itself.

Fixes vercel#58698 (feature request)
Fixes vercel#56368 (caused by next-ws / websocket middleware)
AaronFriel added a commit to AaronFriel/next.js that referenced this issue Dec 1, 2023
Enables route handlers to receive and act on `Connection: Upgrade` requests, such as WebSockets,
when using the Node runtime. To enable this, the base http server has the `on('upgrade')` handler
removed. In this author's opinion, that handler is an anti-pattern as it makes it much more
difficult to handle middleware and other request lifecycle behavior.

By passing the raw request to the route handler and implementing a `NextResponse.upgrade()` response
value to opt out of additional processing that would write to the socket, the route handler can
handle an upgrade request itself.

Fixes vercel#58698 (feature request)
Fixes vercel#56368 (caused by next-ws / websocket middleware)
@spencerchang
Copy link

next.js 14.0.4 this issue still happened.

@tyler-dot-earth
Copy link

I experienced this error message earlier after upgrading to Next v14 — i needed to upgrade my Clerk package, it turned out. The error went away after.

Check any middleware that your middleware may be using.

@github0013
Copy link

github0013 commented Dec 11, 2023

$ /app/node_modules/.bin/next info

Operating System:
  Platform: linux
  Arch: x64
  Version: #82-Ubuntu SMP Tue Jun 6 23:10:23 UTC 2023
Binaries:
  Node: 18.17.1
  npm: 9.6.7
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 13.5.6
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A


warn  - Latest canary version not detected, detected: "13.5.6", newest: "14.0.5-canary.5".
        Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
        Read more - https://nextjs.org/docs/messages/opening-an-issue
Done in 1.62s.

I encountered the same issue today using 13.5.6. No matter what I did, nothing fixed the error. So I started building from scratch, and I rm -fr .next, next build it and next start in each step below.

  1. I created another directly
  2. created a minimal next project running (no issues here)
  3. added middleware.ts from the original (no issues here)
  4. added pages/_app.tsx from the original (no issues here)
  5. added pages/api directly from the original (no issues here)
  6. added pages/* from the original (no issues here)
  7. ... so I added all including yarn.lock, except .next node_modules from the original (no issues here)
  8. ?????

So I don't know why and how the error is gone, but I do not see the TypeError: Cannot read properties of undefined (reading 'bind') repeating in my log anymore...

I surely see this at 389 in node_modules/next/dist/server/base-server.js though.

const origSetHeader = _res.setHeader.bind(_res);

@VanCoding
Copy link

I today had this happening locally and it drove me crazy. Then I realized I had a dev-instance of the app open in a tab, that tried to make websocket requests to the prod app, that doesn't support websockets. So.. false alert 😅

@naseef0
Copy link

naseef0 commented Jan 4, 2024

I'm also facing same issue:
⨯ TypeError: Cannot read properties of undefined (reading 'bind')
at NextNodeServer.handleRequestImpl

Node version: 20.10.0, 18.18.0
Next verson: 14.0.4 app-router

@rodhis
Copy link

rodhis commented Jan 11, 2024

If you're using fallbacks on dynamic pages (i.e., pages like [componentId.jsx] or [componentIdNameDirectory]/index.jsx), set fallback to 'blocking'.

E.g.:

return {
        fallback: 'blocking',
        paths: meetups.map((meetup) => (
            { params: { meetupId: meetup._id.toString(),
            }
    }))
    }

This should fix the issue.

@ya2s
Copy link

ya2s commented Jan 19, 2024

I had this problem after upgrading to 14.1.
It didn't happen in 13.4.2 before the upgrade.
After deleting middleware.ts the error disappeared
Is there any workaround?

@ya2s
Copy link

ya2s commented Jan 26, 2024

@huozhi @ztanner @agustints
I was able to reproduce the problem with minimal configuration
Reproduce by starting locally and accessing localhost:3000/test
https://github.com/yamatsum/nextjs-14.1-sample

@ofirelarat
Copy link

@yamatsum you succeed with finding some solution?
I have the same problem with next 14.0.4 and I don't know why

@ya2s
Copy link

ya2s commented Jan 30, 2024

No, it's not resolved yet
I'm having trouble updating

@spencerchang
Copy link

In my case, it's happened when i include socket.io and enable websocket.
I have no idea to fix it.

@webmak
Copy link

webmak commented Feb 3, 2024

after I've added
export const config = { matcher: [ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], }
this bug disapiered on 14.1

@ztanner
Copy link
Member

ztanner commented Feb 4, 2024

In your reproduction @yamatsum, since you're using a multi-zone approach, when loading /test the dev HMR websocket for web2 is being handled by your middleware in apps/web rather than making it to the server it was intended for (apps/web2). Updating your middleware matcher to exclude paths that correspond the basepath of the other server you're rewriting to (ie anything that starts with /test) will fix the problem. Something like this:

// apps/web/middleware.ts
export const config = {
  matcher: [
    // Don't handle HMR requests for the dev server we rewrite to
    "/((?!test/_next/webpack-hmr).*)",
  ],
};

Note: It's currently important that you use matcher to exclude these paths, rather than skipping over them in the middleware handler itself.

When doing this, it will see that your middleware didn't handle the request, and move onto your rewrites which point the request to your other server.

If you're running into this issue but aren't running a multi-zone setup, then there's likely some other websocket upgrade request that is being handled by your middleware. As mentioned by some folks in earlier replies, make sure your middleware matchers are skipping over those routes so they can make it to the server they were intended for.

We should be able to detect this and handle it more gracefully on our side, so I can work on a fix for that. The above is a workaround in the meantime.

@ya2s
Copy link

ya2s commented Feb 6, 2024

@ztanner Thank you for investigating!
Will the problem be fixed soon?

Also, is it necessary to exclude webpack-hmr?

@ztanner
Copy link
Member

ztanner commented Feb 8, 2024

Hi @yamatsum -- currently yes, you need to exclude it. In a typical single-server setup, that single server handles webpack-hmr requests, so they never make it to your middleware.

But because your first server is seeing an HMR request for a different server, it doesn't know what to do with it, so it's passing it on to middleware for your first server rather than letting it rewrite to your second server.

I don't have an ETA yet on a fix, I will try to look into it next week :)

@ya2s
Copy link

ya2s commented Feb 20, 2024

@ztanner

But because your first server is seeing an HMR request for a different server, it doesn't know what to do with it, so it's passing it on to middleware for your first server rather than letting it rewrite to your second server.

Thank you for your investigation
Did you understand anything?

@Siumauricio
Copy link

In my case none of the above solutions worked

I just set the matcher where i want to run the middleware and it's working

export const config = {
  matcher: ["/", "/register", "/dashboard/:path*"],
};

@woochi
Copy link

woochi commented Mar 10, 2024

@ztanner have you had a chance to look into the issue yet? Thank you in advance.

@spencerchang
Copy link

spencerchang commented Apr 23, 2024

@ztanner i tried every solutions here and
export const config = { matcher: [ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], } is working
But when i turn on countries redirect based on next.js doc like below the redirect not working anymore.
I really looking forward to fix this issue.
Thank you.

`import { NextRequest, NextResponse } from 'next/server'

const PUBLIC_FILE = /.(.*)$/

export async function middleware(req: NextRequest) {
const res = NextResponse.next()
const acceptLanguage = req.headers.get('accept-language')

if (
    req.nextUrl.pathname.startsWith('/_next') ||
    req.nextUrl.pathname.includes('/api/') ||
    PUBLIC_FILE.test(req.nextUrl.pathname)
) {
    return
}

if (req.nextUrl.locale === 'default') {
    let locale = 'tw'
    if (acceptLanguage?.includes('zh-TW')) {
        locale = 'tw'
    } else if (acceptLanguage?.includes('zh-HK')) {
        locale = 'tw'
    } else if (acceptLanguage?.includes('zh-MO')) {
        locale = 'tw'
    } else if (acceptLanguage?.includes('zh-CN')) {
        locale = 'cn'
    } else if (acceptLanguage?.includes('zh')) {
        locale = 'cn'
    } else if (acceptLanguage?.includes('ja')) {
        locale = 'jp'
    } else if (acceptLanguage?.includes('ko')) {
        locale = 'kr'
    } 
    return NextResponse.redirect(
        new URL(
            `/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`,
            req.url
        )
    )
}

}`

@Manuelandro
Copy link

Up

@Markvallejo
Copy link

I today had this happening locally and it drove me crazy. Then I realized I had a dev-instance of the app open in a tab, that tried to make websocket requests to the prod app, that doesn't support websockets. So.. false alert 😅

This is the correct answer @VanCoding

@issam-seghir
Copy link

issam-seghir commented Jun 25, 2024

I have encountered the same issue with "next": "14.2.3" while using it with socket.io.
The problem stems from the middleware. The only solution that worked for me was the one provided by @webmak. I replaced my matcher with the following:

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
}

The TypeError issue has been resolved, but unfortunately, a new error arises with clerck due to a discrepancy in the provided documentation. They suggest using a different match : matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], 😵

@devjiwonchoi
Copy link
Member

@mstys Could not reproduce with the given link, please provide a valid repro. Thank you!

For the future readers, please take a look at the Middleware Matching Paths doc and ensure the config is set correctly.

Also, thank you @issam-seghir, @Siumauricio, @webmak and @smartinio for sharing your working matcher config!

@devjiwonchoi devjiwonchoi closed this as not planned Won't fix, can't repro, duplicate, stale Aug 4, 2024
@devjiwonchoi devjiwonchoi reopened this Aug 6, 2024
@mohammedaslawy
Copy link

The issue is likely due to a compatibility problem with the version of next-auth you are using. I resolved the issue by upgrading to the beta version of next-auth, which resolved the error related to the oidc-token-hash library. Here's what I did:

Upgrade next-auth to the Beta Version:
Run the following command to install the latest beta version of next-auth:

bash

npm install next-auth@beta

@drewcasebeer
Copy link

I also seem to be having this same issue when even using the clerk quickstart here: https://github.com/clerk/clerk-nextjs-app-quickstart. Talking to their support has been primarily pushed back here as the error happening in node_modules/next/dist/server/base-server.js:475:50.

I have tested all of the Middleware matching patterns on here as well as a couple more. Anything else people can think of to check?

@drewcasebeer
Copy link

Small update to the above. I still receive this error even when I create a new project with create-next-app and adding the following middleware.ts file

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
	// Clone the request headers and set a new header `x-hello-from-middleware1`
	const requestHeaders = new Headers(request.headers);
	requestHeaders.set('x-hello-from-middleware1', 'hello');

	// You can also set request headers in NextResponse.next
	const response = NextResponse.next({
		request: {
			// New request headers
			headers: requestHeaders,
		},
	});

	// Set a new response header `x-hello-from-middleware2`
	response.headers.set('x-hello-from-middleware2', 'hello');
	return response;
}

export const config = {
	matcher: [
		// Skip Next.js internals and all static files, unless found in search params
		'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
		// Always run for API routes
		'/(api|trpc)(.*)',
	],
};

@talonx
Copy link

talonx commented Oct 17, 2024

I today had this happening locally and it drove me crazy. Then I realized I had a dev-instance of the app open in a tab, that tried to make websocket requests to the prod app, that doesn't support websockets. So.. false alert 😅

Thank you, this gave me a clue as to what the problem was. I had two Next JS apps, and one was shutdown but the browser tab was still open. When I started the other one it started on the same port and caused this.

@zymantas-katinas
Copy link

I had similar issue running next 15.0.2 app router and next-intl 3.24. It was triggered only when navigating to SSR pages that were generated on request with id passed through params.

What helped me was to set the request locale on these pages, here's an example:

/src/[locale]/listings/[id]/page.tsx

import { setRequestLocale } from "next-intl/server";
import { Listing } from "./listing";

export default async function Page(props: { params: Promise<{ id: string; locale: string }> }) {
  const params = await props.params;
  const { id, locale } = params;

  setRequestLocale(locale);

  return <Listing listingId={id} />;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.