drizzle-team/drizzle-orm · error · DrizzleQueryError

Failed query: ${queryString} params: ${params}

Error message

Failed query: ${queryString}
params: ${params}

What it means

PgPreparedQuery.queryWithCache (session.ts:70-74) wraps the underlying driver query in a try/catch for the no-cache path (cache is undefined, NoopCache, or queryMetadata is undefined). When the driver rejects — constraint violation, syntax error, type mismatch, connection drop, etc. — it is re-thrown as a DrizzleQueryError carrying the rendered SQL string and bound params, with the original error on .cause.

Source

Thrown at drizzle-orm/src/pg-core/session.ts:73

		return this;
	}

	static readonly [entityKind]: string = 'PgPreparedQuery';

	/** @internal */
	joinsNotNullableMap?: Record<string, boolean>;

	/** @internal */
	protected async queryWithCache<T>(
		queryString: string,
		params: any[],
		query: () => Promise<T>,
	): Promise<T> {
		if (this.cache === undefined || is(this.cache, NoopCache) || this.queryMetadata === undefined) {
			try {
				return await query();
			} catch (e) {
				throw new DrizzleQueryError(queryString, params, e as Error);
			}
		}

		// don't do any mutations, if globally is false
		if (this.cacheConfig && !this.cacheConfig.enable) {
			try {
				return await query();
			} catch (e) {
				throw new DrizzleQueryError(queryString, params, e as Error);
			}
		}

		// For mutate queries, we should query the database, wait for a response, and then perform invalidation
		if (
			(
				this.queryMetadata.type === 'insert' || this.queryMetadata.type === 'update'
				|| this.queryMetadata.type === 'delete'
			) && this.queryMetadata.tables.length > 0

View on GitHub (pinned to b7862528fd)

Solutions

  1. Read .cause on the DrizzleQueryError to get the original Postgres error code (e.g., 23505 unique_violation).
  2. Fix the offending data/constraint based on the Postgres SQLSTATE in the cause.
  3. For connection/timeout causes, tune pool size and statement timeouts.
  4. Log the queryString and params (redacted) from the error for debugging.

Example fix

// before
await db.insert(users).values({ email: 'dup@example.com' }); // 23505 unique_violation

// after
try {
  await db.insert(users).values({ email: 'dup@example.com' });
} catch (e) {
  if (e instanceof DrizzleQueryError && (e.cause as any)?.code === '23505') {
    // handle duplicate
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate inputs before sending to avoid common server rejections.
function assertInsertable(row: Record<string, unknown>, required: string[]) {
  for (const col of required) {
    if (row[col] === undefined || row[col] === null) {
      throw new Error(`Missing required column: ${col}`);
    }
  }
}

Type guard

import { DrizzleQueryError } from 'drizzle-orm';

function isPgError(e: unknown, code?: string): e is DrizzleQueryError {
  return e instanceof DrizzleQueryError
    && (code ? (e.cause as any)?.code === code : true);
}

Try / catch

import { DrizzleQueryError } from 'drizzle-orm';

try {
  await db.insert(users).values(row);
} catch (e) {
  if (e instanceof DrizzleQueryError) {
    const pg = e.cause as { code?: string; message?: string } | undefined;
    if (pg?.code === '23505') { /* unique violation */ }
    else if (pg?.code === '23503') { /* foreign key */ }
    else throw e;
  } else throw e;
}

Prevention

When it happens

Trigger: Any executed query that the Postgres server rejects: unique/foreign-key/check constraint violations, NOT NULL failures, undefined_column, invalid input syntax, division by zero, lock contention timeouts, or driver-level connection errors — occurring when caching is not configured.

Common situations: Inserting a duplicate key; violating a foreign key; passing a malformed value (e.g., bad date/UUID); connection pool exhausted mid-query; permission denied for role; transaction aborted by a prior statement.

Related errors


AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03). Data as JSON: /data/errors/864d15d525c37f84.json. Report an issue: GitHub.