prisma: `Error: PrismaClient is unable to be run under the Vercel Edge Runtime.`
Bug description
In next13, If i change any route handlers to run on the edge while prisma is being called from that route handler, i get this error when deploying to vercel:
[17:31:38.494] /vercel/path0/.next/server/app/api/code/route.js:93
[17:31:38.495] In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues`)},o.DbNull=i.instances.DbNull,o.JsonNull=i.instances.JsonNull,o.AnyNull=i.instances.AnyNull,o.NullTypes={DbNull:i.classes.DbNull,JsonNull:i.classes.JsonNull,AnyNull:i.classes.AnyNull},t.Prisma.TransactionIsolationLevel=s({ReadUncommitted:"ReadUncommitted",ReadCommitted:"ReadCommitted",RepeatableRead:"RepeatableRead",Serializable:"Serializable"}),t.Prisma.UserApiLimitScalarFieldEnum={id:"id",userId:"userId",count:"count",createdAt:"createdAt",updatedAt:"updatedAt"},t.Prisma.UserSubscriptionScalarFieldEnum={id:"id",userId:"userId",stripeCustomerId:"stripeCustomerId",stripeSubscriptionId:"stripeSubscriptionId",stripePriceId:"stripePriceId",stripeCurrentPeriodEnd:"stripeCurrentPeriodEnd"},t.Prisma.SortOrder={asc:"asc",desc:"desc"},t.Prisma.QueryMode={default:"default",insensitive:"insensitive"},t.Prisma.NullsOrder={first:"first",last:"last"},t.Prisma.ModelName={UserApiLimit:"UserApiLimit",UserSubscription:"UserSubscription"},t.PrismaClient=class{constructor(){throw Error(`PrismaClient is unable to be run ${l}.
[17:31:38.496]
[17:31:38.496]
[17:31:38.496] Error: PrismaClient is unable to be run under the Vercel Edge Runtime.
[17:31:38.497] In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues
[17:31:38.497] at new t.PrismaClient (/vercel/path0/.next/server/app/api/code/route.js:93:1080)
[17:31:38.497] at 7916 (/vercel/path0/.next/server/app/api/code/route.js:81:948)
[17:31:38.507] at __webpack_require__ (/vercel/path0/.next/server/edge-runtime-webpack.js:25:42)
[17:31:38.507] at /vercel/path0/.next/server/app/api/code/route.js:112:96504
[17:31:38.508] at webpackJsonpCallback (/vercel/path0/.next/server/edge-runtime-webpack.js:158:39)
[17:31:38.508] at /vercel/path0/.next/server/app/api/code/route.js:1:51
[17:31:38.508] at Script.runInContext (node:vm:141:12)
[17:31:38.508] at runInContext (node:vm:291:6)
[17:31:38.508] at evaluateInContext (/vercel/path0/node_modules/next/dist/server/web/sandbox/context.js:357:38)
[17:31:38.509] at getRuntimeContext (/vercel/path0/node_modules/next/dist/server/web/sandbox/sandbox.js:69:9)
[17:31:38.509]
[17:31:38.509] > Build error occurred
[17:31:38.509] Error: Failed to collect page data for /api/code
[17:31:38.510] at /vercel/path0/node_modules/next/dist/build/utils.js:1156:15
[17:31:38.510] at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
[17:31:38.510] type: 'Error'
[17:31:38.510] }
[17:31:38.556] Error: Command "prisma generate && next build" exited with 1
here is a function i created to check api limit:
const { userId } = auth();
if (!userId) {
return false;
}
const userApiLimit = await prismadb.userApiLimit.findUnique({
where: {
userId
}
});
if (!userApiLimit || userApiLimit.count < FREE_CREDITS) {
return true;
} else {
return false;
}
}
when this is called in the route handler as
const freetrial = await checkApiLimit()
vercel gives the error
How to reproduce
- create a next13 app
- create a function in lib/utils.ts where you call prisma
- call it in a route handler that has its runtime in the edge
- deploy the next13 app to vercel
Expected behavior
No response
Prisma information
Prisma Schema:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_PRISMA_URL") // uses connection pooling
directUrl = env("DATABASE_URL_NON_POOLING") // uses a direct connection
}
model UserApiLimit {
id String @id @default(uuid())
userId String @unique
count Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model UserSubscription {
id String @id @default(uuid())
userId String @unique
stripeCustomerId String? @unique @map(name: "stripe_customer_id")
stripeSubscriptionId String? @unique @map(name: "stripe_subscription_id")
stripePriceId String? @unique @map(name: "stripe_price_id")
stripeCurrentPeriodEnd DateTime? @map(name: "stripe_current_period_end")
}```
lib/prisma.ts
```import { PrismaClient } from "@prisma/client"
declare global {
var prisma: PrismaClient | undefined
}
const prismadb = globalThis.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalThis.prisma = prismadb
export default prismadb;
lib/utils.ts
export async function checkApiLimit() {
const { userId } = auth();
if (!userId) {
return false;
}
const userApiLimit = await prismadb.userApiLimit.findUnique({
where: {
userId
}
});
if (!userApiLimit || userApiLimit.count < FREE_CREDITS) {
return true;
} else {
return false;
}
}
/app/api/code/route.ts
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
export const runtime = 'edge';
const openai = new OpenAIApi(configuration);
const instructionMessage: ChatCompletionRequestMessage = {
role: "system",
content: "...."
};
export async function POST(
req: Request
) {
try {
const { userId } = auth();
const body = await req.json();
const { messages } = body;
const freetrial = await checkApiLimit()
const isPro = await checkSubscription();
if (!userId) {
return new NextResponse("Unauthorized", { status: 401 });
}
if (!configuration.apiKey) {
return new NextResponse("OpenAI API Key not configured.", { status: 500 });
}
if (!messages) {
return new NextResponse("Messages are required", { status: 400 });
}
if (!freetrial && !isPro) {
return new NextResponse("You have reached your free trial limit. Please upgrade your account.", { status: 403 });
}
const response = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [instructionMessage, ...messages]
});
await increaseApiLimit();
return NextResponse.json(response.data.choices[0].message);
} catch (error) {
console.log('[CODE_ERROR]', error);
return new NextResponse("Internal Error", { status: 500 });
}
};
Environment & setup
- OS: Windows
- Database: Postgresql
- Node.js version: 20.3.0
Prisma Version
prisma : 5.1.1
@prisma/client : 5.1.1
Current platform : windows
Query Engine (Node-API) : libquery-engine 6a3747c37ff169c90047725a05a6ef02e32ac97e (at node_modules\@prisma\engines\query_engine-windows.dll.node)
Schema Engine : schema-engine-cli 6a3747c37ff169c90047725a05a6ef02e32ac97e (at node_modules\@prisma\engines\schema-engine-windows.exe)
Schema Wasm : @prisma/prisma-schema-wasm 5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e
Default Engines Hash : 6a3747c37ff169c90047725a05a6ef02e32ac97e
Studio : 0.492.0
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 8
- Comments: 25 (8 by maintainers)
my solution: go to https://www.prisma.io/data-platform/accelerate, create account, connect with your current projet, link the url string with your url(by copying the DATABASE_URL that you probably stored at .env), choose the location that near you. Then follow the instruction tha accelerate give you to modify your existing code, it should probably work
BTW: i’m following the same tutorial that antonio made on youtube, i don’t know why he didn’t have the same issue
Hey everyone!
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 🙇If like me you just need get something from the database, for now what i did was a
fetch
to my api.Vercel Edge Runtime Functions
thanks @janpio , I was getting frustrated with the same issue . But using
prisma generate --data-proxy
helped me resolve the issue .Yes, that is one of the core features of Prisma Data Proxy: https://www.prisma.io/data-platform/proxy That being said, this limitation in Data Proxy is pretty weird and I started an internal discussion to remove it so the pooled connection string can be used as well. No reason why our Proxy can not talk to a connection pooler like PgBouncer.
Indeed, sorry I was not aware:
Here are example URLs from my Vercel Postgres:
You should be able to use
POSTGRES_URL_NON_POOLING
in Prisma Data Proxy successfully. Not that it is identical toPOSTGRES_URL
just without the-pooler
after the “number” in the hostname.This happens because probably
This happens because probably you are fetch user using an server action inside jwt callback when u should use the user provided by JWT callback parameter, same for account parameter.
The problem when using this method is that any changes to the user will not take effect in real time, the user will need to relog to reflect the changes.
Edit: misspelling.
Can you describe how your project is set up @ntubrian (or anyone else)? We will remove this limitation soon, and the more projects we have to try it out, the better our development will work. Thanks!
Hi, I got around this issue by using the NON_POOLING url, it seems to be different than the PRISMA_URL
Hi, Sorry for the late response, here is a github link to a next13 app where i highlighted it: https://github.com/aayush-rajagopalan/next13-prisma-edge.
here is the error given in vercel during deployment:
(Thank you for mentioning about the
shadowDatabaseUrl
, I’ll change it on my project 😃 )