drizzle-team/drizzle-orm · error · DrizzleQueryError
Failed query: ${query} params: ${params}
Error message
Failed query: ${query}
params: ${params} What it means
Wraps any underlying MySQL driver error in a DrizzleQueryError during query execution. This throw site (line 79) is the catch in MySqlPreparedQuery.queryWithCache for the no-cache path: cache is undefined, is a NoopCache, or query metadata is absent. Provides uniform error shape with SQL + params and the original driver error on .cause.
Source
Thrown at drizzle-orm/src/mysql-core/session.ts:79
if (cache && cache.strategy() === 'all' && cacheConfig === undefined) {
this.cacheConfig = { enable: true, autoInvalidate: true };
}
if (!this.cacheConfig?.enable) {
this.cacheConfig = undefined;
}
}
/** @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 > 0View on GitHub (pinned to b7862528fd)
Solutions
- Inspect error.cause for the real MySQL driver error (mysql2 error code/message) and address it.
- Log error.query and error.params to reproduce the statement in a MySQL client.
- Verify connection config (host, port, credentials, ssl) in drizzle()/drizzleConfig.
- For deadlocks/lock timeouts, add retry logic or shorten transactions.
Example fix
// before
await db.select().from(users).where(eq(users.email, badEmail));
// after - inspect cause
import { DrizzleQueryError } from 'drizzle-orm/errors';
try {
await db.select().from(users).where(eq(users.email, badEmail));
} catch (e) {
if (e instanceof DrizzleQueryError) {
console.error('SQL:', e.query, 'params:', e.params);
console.error('driver cause:', e.cause);
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate inputs where possible; driver errors otherwise need try/catch
if (query == null) throw new Error('query required'); Type guard
import { DrizzleQueryError } from '~/errors.ts';
function isDrizzleQueryError(e: unknown): e is DrizzleQueryError {
return e instanceof DrizzleQueryError;
} Try / catch
try {
await db.select().from(users).where(eq(users.id, id));
} catch (e) {
if (e instanceof DrizzleQueryError) {
logger.error({ sql: e.query, params: e.params, cause: e.cause });
}
throw e;
} Prevention
- Inspect .cause on DrizzleQueryError for the real MySQL driver error/code.
- Validate inputs and keep schema in sync to avoid constraint errors.
- Configure connection pool and SSL appropriately for your MySQL server.
- Add retry for transient errors like ER_LOCK_DEADLOCK.
When it happens
Trigger: Any execute/iterator/all/get/values call on a MySQL prepared query that fails at the driver level while no caching layer is active. This is the default execution path for MySQL.
Common situations: SQL syntax errors, connection failures, constraint violations, deadlocks, type mismatches between JS params and MySQL columns, or query timeouts against MySQL/PlanetScale.
Related errors
- You have an empty array for "${name}" enum values
- Your "${f.path.join('->')}" field references a column "${tab
- Cannot pass undefined values to any set operator
- No fields selected for table "${tableConfig.tsName}" ("${tab
- No fields selected for table "${tableConfig.tsName}" ("${tab
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/468e3b8843972195.json.
Report an issue: GitHub.