You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: SQLite onConflictDoNothing places the target WHERE after DO NOTHING (partial unique indexes) #6531
I have verified that the bug I'm about to report hasn't been filed before.
What version of drizzle-orm are you using?
1.0.0-rc.4
What version of drizzle-kit are you using?
N/A
Other packages
Node.js 24 (node:sqlite)
Describe the Bug
onConflictDoNothing({ target, where }) in sqlite-core emits the where clause afterdo nothing, which SQLite rejects. This makes it impossible to target a partial unique index.
This is the same bug as #1628, which was fixed for Postgres in #2056, but the fix only touched pg-core/query-builders/insert.ts. The SQLite builder still has:
this.config.onConflict.push(sql` on conflict ${targetSql} do nothing${whereSql}`);
Reproduction
import{DatabaseSync}from'node:sqlite';import{isNull}from'drizzle-orm';import{drizzle}from'drizzle-orm/node-sqlite';import{integer,sqliteTable,text}from'drizzle-orm/sqlite-core';constusers=sqliteTable('users',{id: integer().primaryKey(),email: text().notNull(),deletedAt: integer('deleted_at'),});constclient=newDatabaseSync(':memory:');client.exec(` CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT NOT NULL, deleted_at INTEGER); CREATE UNIQUE INDEX active_users_email_idx ON users (email) WHERE deleted_at IS NULL;`);constdb=drizzle({ client });constquery=db.insert(users).values({email: 'a@example.com'}).onConflictDoNothing({target: users.email,where: isNull(users.deletedAt)});console.log(query.toSQL().sql);query.run();
Actual
insert into"users" ("id", "email", "deleted_at") values (null, ?, null) on conflict ("users"."email") do nothing where ("users"."deleted_at" is null)
DrizzleQueryError: Failed query: ...
cause: Error: near "where": syntax error
Expected
insert into"users" ("id", "email", "deleted_at") values (null, ?, null) on conflict ("users"."email") where ("users"."deleted_at" is null) do nothing
onConflictDoUpdate({ target, targetWhere, set }) already emits the correct order, so a no-op set works in the meantime.
Suggested fix
- this.config.onConflict.push(sql` on conflict ${targetSql} do nothing${whereSql}`);+ this.config.onConflict.push(sql` on conflict ${targetSql}${whereSql} do nothing`);
changed the title [-][BUG]:[/-][+][BUG]: SQLite onConflictDoNothing places the target WHERE after DO NOTHING (partial unique indexes)[/+]on Oct 19, 2026
Activity
[-][BUG]:[/-][+][BUG]: SQLite onConflictDoNothing places the target WHERE after DO NOTHING (partial unique indexes)[/+]