Error: 500 Internal Server Error — This Serverless Function has crashed.
appears when:On the production URL immediately after a successful deploy; dev works fine.
500 Internal Server Error
Your build passed, the deploy turned green, the production URL returns 500. The Vercel function log names the file and line. Five common causes and one fix per cause.
A Vercel 500 error after deploy is a runtime crash inside the serverless function — the build passed, the code is live, but something in the request path threw. Open Vercel Dashboard → Functions, filter by Error, read the first stack trace. It names the file and the failing line. The fix is almost always a missing env var, an unhandled promise, or an edge-runtime mismatch.
Quick fix for Vercel 500 error after deploy
01// lib/env.ts — preflight env validation02import { z } from "zod";03 04const EnvSchema = z.object({05 DATABASE_URL: z.string().url(),06 STRIPE_SECRET_KEY: z.string().startsWith("sk_"),07 OPENAI_API_KEY: z.string().startsWith("sk-"),08 NEXT_PUBLIC_SITE_URL: z.string().url(),09});10 11// Throws at module load if any var is missing — the 500 becomes a build error.12export const env = EnvSchema.parse(process.env);Deeper fixes when the quick fix fails
01 · Wrap external calls in a timeout
Any route that calls Supabase, OpenAI, Stripe, or your own database needs an explicit timeout and an error branch. Vercel’s default function timeout will kill the request before your handler can respond cleanly.
01export async function POST(req: Request) {02 try {03 const body = await req.json();04 const result = await Promise.race([05 externalCall(body),06 new Promise((_, rej) =>07 setTimeout(() => rej(new Error("timeout")), 8000)08 ),09 ]);10 return Response.json(result);11 } catch (err) {12 console.error("route failed", err);13 return Response.json({ error: "internal" }, { status: 500 });14 }15}02 · Switch to the pooled database URL
Serverless isolates each hold a Postgres connection. At load the database refuses new connections and every route 500s with P1001. The pooled endpoint shares a single pool across isolates.
01DATABASE_URL="postgresql://postgres.<ref>:<pw>@aws-0-<region>.pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=5"02DIRECT_URL="postgresql://postgres.<ref>:<pw>@aws-0-<region>.pooler.supabase.com:5432/postgres"03 · Catch server-only imports at build time
Adding the server-only package to any file that holds secrets or server code makes Next.js fail the build if a client component tries to import it — rather than crashing at request time.
01import "server-only";02import { PrismaClient } from "@prisma/client";03 04export const db = new PrismaClient();Why AI-built apps hit Vercel 500 error after deploy
The Next.js production build is not the same program as next dev. Dev has hot module reload, relaxed type checking, forgiving ESM resolution, and no bundle tree-shaking. Production has strict module resolution, hard boundaries between edge and Node.js runtimes, and a build that fails silently when imports resolve to undefined. An AI-generated file that imports fs at the top level runs fine in dev because Node.js has fs. Deployed with export const runtime = "edge", the same import throws at request time because the Edge runtime does not expose fs. The page 500s. The log says so. But if nobody reads the log, it looks random.
The second structural cause is the unbounded promise. AI-generated API routes frequently call an external service (Supabase, OpenAI, Stripe) without a timeout and without explicit error handling. The external service takes 30 seconds. Vercel’s default function timeout is 10 seconds on Hobby, 60 on Pro. The function times out, the response is 500, and the next request reuses the same function instance which may still be holding the pending connection. The fix is always to wrap external calls in a timeout and handle the error explicitly, so the function fails predictably instead of unpredictably.
The third repeat cause is connection exhaustion. Prisma, Supabase-js, and any ORM that opens its own Postgres connections will die when every serverless isolate holds one. Under enough traffic the database refuses new connections and every API route returns 500 with P1001. The immediate fix is the pooled DATABASE_URL (port 6543 on Supabase, pooled endpoint on Neon). The long-term fix is an APM with alerting on connection pool saturation so you see it coming before every route fails.
“Dev works, prod 500s. The log names the file. Rollbacks just buy you time.”
Vercel 500 error after deploy by AI builder
How often each AI builder ships this error and the pattern that produces it.
| Builder | Frequency | Pattern |
|---|---|---|
| Lovable | High | Non-null assertion on process.env; no edge/node awareness in generated API routes |
| Bolt.new | High | Webhook routes without try/catch; StackBlitz preview masks the unhandled rejection |
| v0 | Medium | Ships edge runtime by default; first fs or native module import blows up in prod |
| Cursor | Medium | Database client created at module scope; exhausts pool under load |
| Claude Code | Low | Usually wraps calls, but occasionally forgets to add env var to Vercel after adding to .env |
Related errors we fix
Stop Vercel 500 error after deploy recurring in AI-built apps
- →Validate process.env with zod at module load so a missing var fails the build, not the request.
- →Add import "server-only" to every file that touches secrets or a database client.
- →Pin every external call to Promise.race with an 8s timeout and an explicit error response.
- →Run a k6 smoke in CI at 10 concurrent users for 2 minutes before promoting the build.
- →Wire a Vercel log drain (Datadog, Axiom, Better Stack) with an alert on 500 rate > 0.1 percent.
Still stuck with Vercel 500 error after deploy?
If you cannot get past the first stack trace or the 500 is intermittent and region-scoped, a fixed-price engagement ships this week:
- →Site is down right now and rollback didn't stick
- →Function log shows a stack trace you cannot reverse-map
- →500s fire only under load or only in one region
- →You need the root-cause report, not another hotfix
Vercel 500 error after deploy questions
Why does my app return a Vercel 500 error after deploy when dev works fine?+
How do I find the real error for a Vercel 500 after deploy?+
Can I reproduce a Vercel 500 after deploy locally?+
What does a runtime mismatch Vercel 500 error look like?+
How much does a Vercel 500 error after deploy cost to resolve?+
Ship the fix. Keep the fix.
Emergency Triage restores service in 48 hours. Break the Fix Loop rebuilds CI so this error cannot ship again.
Hyder Shah leads Afterbuild Labs, shipping production rescues for apps built in Lovable, Bolt.new, Cursor, Replit, v0, and Base44. our rescue methodology.
Vercel 500 error after deploy experts
If this problem keeps coming back, you probably need ongoing expertise in the underlying stack.