drizzle-team/drizzle-orm · error · Error
Cannot execute a query on a query builder. Please use a data
Error message
Cannot execute a query on a query builder. Please use a database instance instead.
What it means
Thrown by MySqlSelectBase.prepare (line 1130) when this.session is undefined. Select builders created from a QueryBuilder instance (new QueryBuilder() or the $db builder) have no session and therefore cannot execute. Only a db instance (which carries a session) can run queries.
Source
Thrown at drizzle-orm/src/mysql-core/query-builders/select.ts:1130
TResult = SelectResult<TSelection, TSelectMode, TNullabilityMap>[],
TSelectedFields = BuildSubquerySelection<TSelection, TNullabilityMap>,
> extends MySqlSelectQueryBuilderBase<
MySqlSelectHKT,
TTableName,
TSelection,
TSelectMode,
TPreparedQueryHKT,
TNullabilityMap,
TDynamic,
TExcludedMethods,
TResult,
TSelectedFields
> {
static override readonly [entityKind]: string = 'MySqlSelect';
prepare(): MySqlSelectPrepare<this> {
if (!this.session) {
throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.');
}
const fieldsList = orderSelectedFields<MySqlColumn>(this.config.fields);
const query = this.session.prepareQuery<
MySqlPreparedQueryConfig & { execute: SelectResult<TSelection, TSelectMode, TNullabilityMap>[] },
TPreparedQueryHKT
>(this.dialect.sqlToQuery(this.getSQL()), fieldsList, undefined, undefined, undefined, {
type: 'select',
tables: [...this.usedTables],
}, this.cacheConfig);
query.joinsNotNullableMap = this.joinsNotNullableMap;
return query as MySqlSelectPrepare<this>;
}
execute = ((placeholderValues) => {
return this.prepare().execute(placeholderValues);
}) as ReturnType<this['prepare']>['execute'];
private createIterator = (): ReturnType<this['prepare']>['iterator'] => {View on GitHub (pinned to b7862528fd)
Solutions
- Execute selects from a db instance: const db = drizzle(...); db.select().from(t).execute();
- If you built a query with QueryBuilder for reuse, pass it to a db via db.$withRecursive or run its SQL with db.execute(sql`...`).
- Make sure you're not accidentally destructuring select off a QueryBuilder instead of db.
Example fix
// before - QueryBuilder has no session
import { QueryBuilder } from 'drizzle-orm/mysql-core';
const qb = new QueryBuilder();
await qb.select().from(users).execute(); // throws
// after - use a db instance
import { drizzle } from 'drizzle-orm/mysql2';
const db = drizzle(client);
await db.select().from(users).execute(); Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure you execute from a db, not a QueryBuilder
if (!('session' in dbOrBuilder) || !(dbOrBuilder as any).session) {
throw new Error('Use a drizzle() db instance to execute queries');
} Type guard
import { MySqlDatabase } from '~/mysql-core/db.ts';
function isExecutableDb(v: unknown): v is MySqlDatabase<any, any, any, any> {
return v instanceof MySqlDatabase;
} Prevention
- Always execute from a drizzle() db instance.
- Don't confuse QueryBuilder with db; QueryBuilder composes SQL only.
- If composing with QueryBuilder, run the resulting SQL via db.execute(sql`...`).
When it happens
Trigger: Constructing a select via a QueryBuilder (not a db) and then calling .execute(), .prepare(), .all(), or iterating. The QueryBuilder is meant for composing SQL to be run elsewhere, not for direct execution.
Common situations: Using `import { QueryBuilder } from 'drizzle-orm/mysql-core'; const qb = new QueryBuilder(); qb.select().from(t).execute();` - qb has no session. Confusing QueryBuilder with the db instance.
Related errors
- Your "${f.path.join('->')}" field references a column "${tab
- Cannot execute a query on a query builder. Please use a data
- Cannot execute a query on a query builder. Please use a data
- Cannot execute a query on a query builder. Please use a data
- 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/e4ea7b1253581574.json.
Report an issue: GitHub.