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

Can't use Prisma client in Next.js middleware, even when deploying to Node.js #21310

Closed
markspolakovs opened this issue Oct 2, 2023 · 41 comments
Labels
bug/2-confirmed Bug has been reproduced and confirmed. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. status/is-preview-feature This feature request is currently available as a Preview feature. tech/typescript Issue for tech TypeScript. topic: deployment/vercel topic: edge runtime topic: Next.js middleware topic: Next.js topic: Vercel Edge Middleware
Milestone

Comments

@markspolakovs
Copy link

Bug description

Next.js middleware seems to fail the edge runtime check, even when deployed to Node.js:

Error: PrismaClient is unable to run in Vercel Edge Functions. As an alternative, try Accelerate: https://pris.ly/d/accelerate.
If this is unexpected, please open an issue: https://github.com/prisma/prisma/issues

Wasn't sure if this is a Next or a Prisma bug.

How to reproduce

  1. Clone https://github.com/markspolakovs/next-prisma-repro
  2. Run yarn dev
  3. Visit http://localhost:3000
image

Expected behavior

DB operations to work inside middleware.

Prisma information

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

model User {
  id Int @id @default(autoincrement())
}
import { PrismaClient } from "@prisma/client";
import { NextRequest, NextResponse } from "next/server";

const prisma = new PrismaClient();

export async function middleware(req: NextRequest): Promise<NextResponse> {
  const user = await prisma.user.findFirst();
  return NextResponse.next();
}

Environment & setup

  • OS: macOS arm64
  • Database: SQLite
  • Node.js version: v18.17.0

Prisma Version

prisma                  : 5.3.1
@prisma/client          : 5.3.1
Current platform        : darwin-arm64
Query Engine (Node-API) : libquery-engine 61e140623197a131c2a6189271ffee05a7aa9a59 (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Schema Engine           : schema-engine-cli 61e140623197a131c2a6189271ffee05a7aa9a59 (at node_modules/@prisma/engines/schema-engine-darwin-arm64)
Schema Wasm             : @prisma/prisma-schema-wasm 5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59
Default Engines Hash    : 61e140623197a131c2a6189271ffee05a7aa9a59
Studio                  : 0.494.0
@markspolakovs markspolakovs added the kind/bug A reported bug. label Oct 2, 2023
@Junko-Takeguchi
Copy link

@markspolakovs you should try importing the prisma client like this
import { PrismaClient } from '@prisma/client/edge
for the edge functions.

@aqrln aqrln added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. topic: Next.js topic: deployment/vercel tech/typescript Issue for tech TypeScript. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. labels Oct 5, 2023
@Hunam6
Copy link

Hunam6 commented Nov 2, 2023

Same issue here.
There were some previous talk here #9928. But it's quite old, I think the situation has changed.
NextJS middlewares are really useful for performance or authentication with next-auth@beta for example. NextJS's official "book"/tutorial uses a middleware with next-auth.

@millsp
Copy link
Member

millsp commented Nov 7, 2023

@markspolakovs @prisma/client is not able to run in Vercel Edge Middleware (or Vercel Edge Functions), as mentioned in the message. The only way to currently get this working, is to use Prisma Accelerate and change your import to @prisma/client/edge.

@millsp millsp added bug/2-confirmed Bug has been reproduced and confirmed. and removed bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Nov 7, 2023
@markspolakovs
Copy link
Author

Thanks for confirming @millsp. Is this still true if I'm self-hosting my Next app (using Docker), rather than running it on Vercel?

@millsp
Copy link
Member

millsp commented Nov 7, 2023

Hmm, I am trying to think what we could do to workaround this. Next.js is bundling your project, and it will bundle the separate edge function via the browser field (hence this special error). So if would try a few things to prevent that, since you are running that function on Node.js why pick the browser version anyways? I can imagine two ways to bypass the bundling of browser:

  • I'd try to see if there is any way to mark @prisma/client dependency as external on the edge function. I don't think this is possible though, maybe by fiddling with their webpack or swc config.
  • Probably the easier way to bypass the browser entrypoint being bundled, would be to provide the full path to the generated prisma client. Something like import { PrismaClient } from '../node_modules/.prisma/client/index. This should force Next.js not to use the browser entrypoint and just stick to index.

You may get other hurdles down the line (eg. engine or schema not being copied in the correct locations), happy to assist as needed.

@clemenspeters
Copy link

Pretty annoying. Moving the very same function call out of the middleware and it works.
This was my workaround for now, but I would have preferred to keep the code in the middleware where it was before we started using Primsa. 🙈

@markspolakovs
Copy link
Author

Unfortunately it looks like Next's edge runtime blocks all this trickery: I tried the client/index import that @millsp suggested, and also set unstable_allowDynamic in my middleware config, but Prisma Client still fails to load:

 ⨯ Error [TypeError]: wr1.deprecate is not a function
    at <unknown> (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:388)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:388:22)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:16:30)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:524:128)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:16:30)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/runtime/library.js:1064:12)
    at (middleware)/../utility/prisma/client/runtime/library.js (file:///Users/marks/code/bowser/server/.next/server/middleware.js:1117:1)
    at __webpack_require__ (file:///Users/marks/code/bowser/server/.next/server/edge-runtime-webpack.js:37:33)
    at fn (file:///Users/marks/code/bowser/server/.next/server/edge-runtime-webpack.js:325:21)
    at eval (webpack-internal:///(middleware)/../utility/prisma/client/index.js:6:324)
    at (middleware)/../utility/prisma/client/index.js (file:///Users/marks/code/bowser/server/.next/server/middleware.js:1095:1)

(I ran runtime/library.js through prettier to help with debugging, hence the line numbers being different.)

It looks like it's getting tripped up on Prisma requiring debug which then requires Node's util module to call util.deprecate - unfortunately I'd imagine that trying to solve this will just lead to a game of whack-a-mole with various Node modules the Edge Runtime doesn't support.

I found a feature request on the Next side to allow configuring middleware to use the Node runtime, but with no response from the Next team: vercel/next.js#38989

@ChrisB1123
Copy link

ChrisB1123 commented Dec 5, 2023

A solution for anyone else who ran into this error just trying to set up a project - I believe you can just use jwt sessions, rather than database sessions.

export const config = {
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },      // Add this line
  callbacks: ...
  providers: ...,
} satisfies NextAuthConfig;

@mamlzy

This comment was marked as outdated.

@satyaprakash-yadav

This comment was marked as off-topic.

@iMerica
Copy link

iMerica commented Feb 22, 2024

Why would querying the DB be any different in middleware than in a server component? To the DB client, it's all just a Node.js runtime.

I hope I'm wrong, but this seems like a deliberate limitation to sell some commercial feature. Which is really outside the spirit and ethos of open source (see OSI).

 ⨯ PrismaClient is unable to run in Vercel Edge Functions or Edge Middleware. As an alternative, try Accelerate: https://pris.ly/d/accelerate.

@janpio
Copy link
Contributor

janpio commented Feb 22, 2024

Vercel Edge Middleware is not a Node.js runtime, but the Vercel Edge Runtime. Prisma currently can not run in that environment as it does not allow talking to databases via the normal database drivers using the normal methods like TCP connections - which Prisma usually uses.

@iMerica
Copy link

iMerica commented Feb 22, 2024

@janpio Might be true, but that is not a relevant fact in my case since I don't use Vercel. I deploy Next.js apps as Docker containers that run in Kubernetes. The base Docker image is always node:21-alpine.

@janpio
Copy link
Contributor

janpio commented Feb 22, 2024

Then you should open a bug report instead of assuming ill intent, so we can look into that, because that of course should not happen. Obviously the error message is incorrect, and we want to look into that and fix it. (I am not fully sure if that is also the case above, so an additional bug issue with information and optimally a reproduction would be very helpful.)

PS: We are also currently working on, and have a private Early Access running, for support of Vercel Edge Middleware: #21394

@goleary
Copy link

goleary commented Mar 11, 2024

IMO this issue is about this error message appearing even and preventing usage of prisma in middleware when not using Vercel in any way, not that the prisma client can't be used in the vercel edge runtime.

@janpio The original reproduction from this issue should do the trick.

@janpio
Copy link
Contributor

janpio commented Mar 12, 2024

The Next.js documentation has the answer to the problem:

image

Runtime

Middleware currently only supports the Edge runtime. The Node.js runtime can not be used.

Source https://nextjs.org/docs/app/building-your-application/routing/middleware#runtime

So even when you run your Next.js app locally via Node.js, it unfortunately still runs the middleware via the Edge middleware instead.

@janpio
Copy link
Contributor

janpio commented Mar 12, 2024

Fortunately, we just released Prisma ORM version 5.11.0 which includes a preview feature for Edge Functions support for Vercel Edge Functions and Middleware (and Cloudflare Workers and Pages) in Prisma ORM 🥳

Please give it a try, and let us know how it goes! If you encounter any problems, please create a new bug report issue, or if the problem is driver adapter specific, use the feedback discussions for @prisma/adapter-neon, @prisma/adapter-planetscale, or @prisma/adapter-libsql / Turso 🙇


With that I was able to upgrade the reproduction from the original issue description to Prisma 5.11.0, and use a PostgreSQL database from Neon (or Vercel Postgres): markspolakovs/next-prisma-repro#1 (Unfortunately the Edge Runtime does not support reading local files, so using SQLite - which is a local file - is out of the question, so I had to switch to using PostgreSQL.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/2-confirmed Bug has been reproduced and confirmed. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. status/is-preview-feature This feature request is currently available as a Preview feature. tech/typescript Issue for tech TypeScript. topic: deployment/vercel topic: edge runtime topic: Next.js middleware topic: Next.js topic: Vercel Edge Middleware
Projects
None yet
Development

No branches or pull requests