Prisma: prepared statement "s0" already exists
Prisma migrate or a Supabase pooler query says prepared statement s0 already exists? The command is going through PgBouncer. Point Migrate at a direct URL.
Reviewed October 15, 2026
What it means in plain English
Prisma uses named prepared statements. PgBouncer, and Supabase's Supavisor pooler, do not always keep those statements on the same connection. Prisma's PgBouncer guide shows this error when Migrate runs through the pooler:
Error querying the database: db error: ERROR: prepared statement "s0" already exists
Likely causes
DATABASE_URLis the pooled Supabase string (often port 6543), andprisma migrateorprisma db pushuses it.- The runtime client and the CLI share one URL.
?pgbouncer=trueis missing on an older pooler, or it was added to the direct URL as well.
How to fix it, step by step
- Keep two URLs. Prisma's example is
DATABASE_URLfor the pooler, with?pgbouncer=true, andDIRECT_URLfor a direct Postgres connection. - Point Prisma CLI at the direct URL in
prisma.config.ts(datasource.url). Prisma says Migrate does not support going through PgBouncer, and CLI commands should use that direct string. - Point Prisma Client at the pooled URL through the driver adapter. Prisma's Supabase note says Supavisor behaves like PgBouncer and that you can add
?pgbouncer=trueto the pooled string from the Supabase database settings. - For a PgBouncer at version 1.21.0 or newer, Prisma says you generally do not need
pgbouncer=true, and that the pooler should be in transaction mode. The "s0 already exists" error on Migrate is still fixed by using the direct URL for CLI commands.
How to check it worked
prisma migrate deployorprisma db pushcompletes using the direct host.- The running app still connects with the pooled host, and the s0 error is gone from the deploy log.
Sources
Related fixes
More Database connections fixes
Keep going on your own.
The guides stay free. A deep leak report is $15. Fix packs are $24, or $49 for all three. There is no done-for-you repair.