next-auth icon indicating copy to clipboard operation
next-auth copied to clipboard

"Failed to load external module node:module" when attempting to use middleware with Prisma and Neon serverless

Open tremby opened this issue 8 months ago • 21 comments

Environment

  System:
    OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
    CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
    Memory: 22.17 GB / 31.28 GB
    Container: Yes
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.10.0/bin/yarn
    npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
    pnpm: 9.7.1 - ~/.nvm/versions/node/v20.10.0/bin/pnpm
  Browsers:
    Chromium: 135.0.7049.84
  npmPackages:
    @auth/prisma-adapter: ^2.8.0 => 2.8.0
    @neondatabase/serverless: ^1.0.0 => 1.0.0
    next: 15.3.0 => 15.3.0
    next-auth: ^5.0.0-beta.25 => 5.0.0-beta.25
    prisma: ^6.6.0 => 6.6.0
    react: ^19.0.0 => 19.1.0

Reproduction URL

https://github.com/tremby/auth-test

Describe the issue

I'm trying to get Nextjs, Authjs/next-auth and its middleware, Prisma, and Neon all working together.

I understand that getting databases to work in edge runtimes is tricky, but the docs say that it is supported with various drivers including the Neon serverless one. I'm using Neon, so that sounds OK to me.

The documentation is difficult to follow, since it boots me off to the Prisma site, and also to the Neon site, and each one seems to give slightly different instructions.

I've done my best to follow the instructions. The most straightforward route through the docs which looks to my eye like it ought to be complete is included in the reproduction repo. Step through its commits and see the messages for details. Not included in the reproduction repo, I also tried various different versions and combinations of the instructions, anything I could find.

With every iteration, when running npm run dev and navigating to localhost:3000 I see a stack trace, and in the console I have a lot of these:

 ⨯ [Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization]

How to reproduce

  1. Check out the reproduction repo
  2. npm install
  3. cp .env.example .env
  4. vim .env and fill in values
  5. npx prisma generate
  6. npm run dev
  7. Navigate to localhost:3000
  8. See stack trace and console output

Expected behavior

Middleware executes successfully. Page loads. No errors.

tremby avatar Apr 17 '25 01:04 tremby

+1 - similar behaviour with Prisma and local Postgres.

Followed this guide to setup Prisma: https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases-typescript-postgresql

Followed this guide for Auth.js + Prisma configuration: https://authjs.dev/getting-started/adapters/prisma

Hope this helps!

WillMorrow avatar Apr 17 '25 23:04 WillMorrow

+1 - similar behaviour with Prisma and local Postgres. ... Hope this helps!

I find it unclear from your message whether you have it working or not.

I'm trying to use Neon Serverless, which Prisma's docs say is one of the database drivers which is edge-compatible (and therefore hopefully middleware-compatible). Which driver are you using?

tremby avatar Apr 17 '25 23:04 tremby

+1 - similar behaviour with Prisma and local Postgres.

I find it unclear from your message whether you have it working or not.

Apologies for the confusion - to clarify, I am facing the same issue as yourself and I do not have a working fix as yet.

WillMorrow avatar Apr 18 '25 10:04 WillMorrow

Running into the same issue but standalone. Not serverless. Everything was running fine and then added the middleware and boom.

Prisma Postgres "next-auth": "^5.0.0-beta.25",

Barebones middleware.ts

export { auth as middleware } from "@/lib/auth"

Stack trace.

Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization
    at Object.externalRequire [as x] (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:1448:15)
    at [project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript) (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/node_modules_@prisma_client_e24b49d2._.js:41:74)
    at <unknown> (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:722:27)
    at runModuleExecutionHooks (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:768:9)
    at instantiateModule (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:720:9)
    at getOrInstantiateModuleFromParent (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:653:12)
    at esmImport (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:143:20)
    at [project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript) (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/node_modules_99b3511c._.js:4281:191)
    at <unknown> (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:722:27)
    at runModuleExecutionHooks (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:768:9)

martyphee avatar Apr 19 '25 08:04 martyphee

I got the same issue as you.

  System:
    OS: Linux 5.15 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
    CPU: (12) x64 Intel(R) Core(TM) i7-7800X CPU @ 3.50GHz
    Memory: 8.32 GB / 15.47 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v22.12.0/bin/yarn
    npm: 10.9.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
    pnpm: 10.6.1 - ~/.local/share/pnpm/pnpm
  Browsers:
    Chrome: 135.0.7049.52
  npmPackages:
    @auth/prisma-adapter: ^2.8.0 => 2.8.0 
    next: 15.3.1 => 15.3.1 
    next-auth: ^5.0.0-beta.25 => 5.0.0-beta.25 
    react: ^19.0.0 => 19.1.0 

I am not using Neon at all but got the same error using basic install process.

Object.externalRequire [as x]
[turbopack]/shared-node/base-externals-utils.ts (41:11)
[project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript)
node_modules/@prisma/client/runtime/library.mjs (1:1)
<unknown>
[turbopack]/browser/runtime/base/dev-base.ts (201:21)
runModuleExecutionHooks
[turbopack]/browser/runtime/base/dev-base.ts (261:5)
instantiateModule
[turbopack]/browser/runtime/base/dev-base.ts (199:5)
getOrInstantiateModuleFromParent
[turbopack]/browser/runtime/base/dev-base.ts (128:10)
esmImport
[turbopack]/shared/runtime-utils.ts (214:18)
[project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript)
node_modules/@auth/prisma-adapter/index.js (1:1)
<unknown>
[turbopack]/browser/runtime/base/dev-base.ts (201:21)
runModuleExecutionHooks
[turbopack]/browser/runtime/base/dev-base.ts (261:5)

tintin92350 avatar Apr 19 '25 12:04 tintin92350

I am having the same error with a similar stack :

The problem has been resolved.

follow this guide: Neon Edge Compatibility

// auth.ts
// This file is responsible for setting up authentication using NextAuth.js and Prisma.

import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import authConfig from "./auth.config";
import prisma from "@/lib/prisma";

export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: {
    strategy: "jwt",
  },
  ...authConfig,
});
// auth.config.ts
// This file is responsible for configuring authentication providers and settings.

import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";

export default { providers: [Google] } satisfies NextAuthConfig;
// prisma.ts
// This file is responsible for setting up the Prisma client and database connection.

import { neonConfig } from "@neondatabase/serverless";
import { PrismaClient } from "@prisma/client";
import ws from "ws";

declare global {
  // eslint-disable-next-line no-var
  var prisma: PrismaClient | undefined;
}

const connectionString = `${process.env.DATABASE_URL}`;
neonConfig.webSocketConstructor = ws;
const prisma =
  global.prisma ||
  new PrismaClient({ datasources: { db: { url: connectionString } } });

export default prisma;

if (process.env.NODE_ENV === "development") global.prisma = prisma;

gmsetiawan avatar Apr 19 '25 15:04 gmsetiawan

@gmsetiawan, I tried using your example code above and I still see the same error.

I committed that to a branch of my test repo: https://github.com/tremby/auth-test/tree/gmsetiawan

If you'd be so kind, please check that out and let me know what I've missed.

tremby avatar Apr 19 '25 17:04 tremby

@tremby

Try it

// middleware.ts
// This file is used to configure NextAuth.js middleware
// and protect routes in the application.

import authConfig from "./auth.config";
import NextAuth from "next-auth";

export const { auth: middleware } = NextAuth(authConfig);

Everything running as you want.

gmsetiawan avatar Apr 20 '25 03:04 gmsetiawan

It's working for me now. Thank you.

Using both password and google login.

martyphee avatar Apr 20 '25 07:04 martyphee

Same issue here. Using PlanetScale, Turbopack and experimental Node middleware.

next: 15.3.1-canary.15 next-auth: 5.0.0-beta.26 @auth/core: 0.39.0 @auth/prisma-adapter: 2.9.0

Runtime Error

Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization

Object.externalRequire [as x]
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (1448:15)
[project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript)
.next\server\edge\chunks\node_modules_@prisma_client_2a1680e0._.js (41:74)
<unknown>
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (722:27)
runModuleExecutionHooks
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (768:9)
instantiateModule
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (720:9)
getOrInstantiateModuleFromParent
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (653:12)
esmImport
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (143:20)
[project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript)
.next\server\edge\chunks\node_modules_fb4e896c._.js (4247:191)
<unknown>
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (722:27)
runModuleExecutionHooks
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (768:9)

ahkhanjani avatar Apr 20 '25 15:04 ahkhanjani

Same problem here when using Next.JS Prisma and Local PostgreSQL. Disable Turbopack helps but didn't solve the problem. Any workaround?

charlieJ107 avatar Apr 20 '25 17:04 charlieJ107

I'm using @auth/prisma-adapter v2.7.4 to make it work

eduardochiaro avatar Apr 20 '25 19:04 eduardochiaro

@gmsetiawan

Try it

// middleware.ts
// This file is used to configure NextAuth.js middleware
// and protect routes in the application.

import authConfig from "./auth.config";
import NextAuth from "next-auth";

export const { auth: middleware } = NextAuth(authConfig);

Everything running as you want.

OK, I made that change, and it's no longer erroring. It appears to also work without forcing the session stategy to JWT.

But if I understand correctly what this is doing, it's not actually connecting to the database at all. In the middleware file you have it passing configuration to NextAuth which doesn't include the database adapter at all. And I think that'll mean that if I'm not using the JWT strategy, then the middleware's purpose, to refresh tokens, isn't going to be achieved.

tremby avatar Apr 21 '25 23:04 tremby

@eduardochiaro

I'm using @auth/prisma-adapter v2.7.4 to make it work

Interesting.

I just tried this and that does get me past that error. But now it's complaining that it doesn't have the connection string. It seems middleware doesn't load environment variables. If I try to manually load them, whether with @next/env or dotenv, I get an error saying that process.cwd isn't supported in the edge runtime environment.

Can you tell us how you got around that, please?

tremby avatar Apr 21 '25 23:04 tremby

Can confirm that rolling back to @auth/prisma-adapter 2.7.4 resolved my issue (I'm using prisma + postgres)

drewhack avatar Apr 25 '25 00:04 drewhack

For me I rolled back @auth/prisma-adapter for 2.7.4 But that alone didn't solve it, I had to add the runtime configuration for nodejs

In next.config.ts experimental: { nodeMiddleware: true, },

And in middleware file

export const config = { runtime: 'nodejs', }

This worked for me

Some links that helped me NextJS, Auth.js and Postgres. Any way to make this combo work? Next.js runtime config

Rodrigo001-dev avatar Apr 26 '25 04:04 Rodrigo001-dev

This can be resolved by using two different config for middleware and other things because in next js middleware runs on edge runtime which will not support adapters that we use because database are not compatible running on edge so we segregate config in two parts as below and use config that doesn't contain adapter in middleware.

// auth.config.ts
import GitHub from "next-auth/providers/github";
import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";

// Notice this is only an object, not a full Auth.js instance
export default {
  providers: [GitHub, Google],
} satisfies NextAuthConfig;
// middleware.ts
import NextAuth from "next-auth";
import authConfig from "./auth.config";

export const { auth: middleware } = NextAuth(authConfig);

Finally for normal use cases other than middleware

// auth.ts
import NextAuth from "next-auth";
import authConfig from "./auth.config";

import { PrismaClient } from "@prisma/client";
import { PrismaAdapter } from "@auth/prisma-adapter";

const prisma = new PrismaClient();

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },
  ...authConfig,
});

Thank you!

RadheyMugdal avatar Apr 28 '25 17:04 RadheyMugdal

Downgrading to @auth/prisma-adapter 2.7.2 should solve it. There is an open issue for this, see https://github.com/nextauthjs/next-auth/issues/12731

ArjunDahal999 avatar Apr 29 '25 05:04 ArjunDahal999

What worked for me was the downgrade @auth/prisma-adapter to 2.7.4. but I needed to do a lot of changes to turn Prisma able to work with auth middleware with any errors, main was to separate AuthOptions and in this ways:

//authServer.ts
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import db from "@/lib/db/db";
import { authOptions } from "./authOptions";

export const { handlers, signIn, signOut, auth } = NextAuth({
  ...authOptions,
  adapter: PrismaAdapter(db),
});
//middleware.ts

import { authOptions } from '@/lib/auth/authOptions';
import NextAuth, { NextAuthConfig } from "next-auth";
import { NextResponse } from "next/server";

// Middleware auth WITHOUT Prisma
const { auth } = NextAuth(authOptions)

export default async function middleware(req: Request) {
  const session = await auth(req as any);

  if (!session) {
    return NextResponse.redirect(new URL("/auth/signin", req.url));
  }

  return NextResponse.next();
}

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

and

// authOptions.ts

import { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";

export const authOptions = {
  providers: [Google],
  secret: process.env.AUTH_SECRET,
  session: {
    strategy: "jwt",  // ---> this line was important to avoid errors
  },

  // Important: keep all  callbacks & configs that affects the session
} as NextAuthConfig;

Maybe somethings was specific because I try external credentials and use MongoDB as database.

vilelalabs avatar May 04 '25 02:05 vilelalabs

+1

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

viktorkasap avatar May 04 '25 17:05 viktorkasap

Downgrading prisma-adapter version to 2.7.4 solves it.

karolsamsel avatar May 06 '25 17:05 karolsamsel