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
PgSelectBase._prepare (select.ts:1080) throws when the query builder has no session, because executing requires a database connection to prepare the statement. A select built from a standalone QueryBuilder (new QueryBuilder()) or detached from a db instance carries no session and therefore cannot run.
Source
Thrown at drizzle-orm/src/pg-core/query-builders/select.ts:1081
TSelectedFields = BuildSubquerySelection<TSelection, TNullabilityMap>,
> extends PgSelectQueryBuilderBase<
PgSelectHKT,
TTableName,
TSelection,
TSelectMode,
TNullabilityMap,
TDynamic,
TExcludedMethods,
TResult,
TSelectedFields
> implements RunnableQuery<TResult, 'pg'>, SQLWrapper {
static override readonly [entityKind]: string = 'PgSelect';
/** @internal */
_prepare(name?: string): PgSelectPrepare<this> {
const { session, config, dialect, joinsNotNullableMap, authToken, cacheConfig, usedTables } = this;
if (!session) {
throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.');
}
const { fields } = config;
return tracer.startActiveSpan('drizzle.prepareQuery', () => {
const fieldsList = orderSelectedFields<PgColumn>(fields);
const query = session.prepareQuery<
PreparedQueryConfig & { execute: TResult }
>(dialect.sqlToQuery(this.getSQL()), fieldsList, name, true, undefined, {
type: 'select',
tables: [...usedTables],
}, cacheConfig);
query.joinsNotNullableMap = joinsNotNullableMap;
return query.setToken(authToken);
});
}
View on GitHub (pinned to b7862528fd)
Solutions
- Build queries from a real db instance (drizzle(...)) so the session is attached: db.select().from(t).
- Pass the db into helper functions rather than constructing a standalone QueryBuilder.
- If you only need the SQL string, use qb.toSQL() or build the SQL without calling execute.
Example fix
// before const qb = new QueryBuilder(); await qb.select().from(users).execute(); // no session -> error // after const db = drizzle(client); await db.select().from(users).execute();
Defensive patterns
Strategy: validation
Validate before calling
// Ensure queries are built from a db instance, never a bare QueryBuilder.
function assertDb<T extends { session: unknown }>(db: T): asserts db is T & { session: object } {
if (!db || !(db as any).session) {
throw new Error('A db instance with a session is required to execute queries');
}
}
assertDb(db);
await db.select().from(users).execute(); Type guard
function isBindableDb(db: unknown): db is { select: Function; execute: Function } {
return db != null && typeof (db as any).select === 'function'
&& typeof (db as any).execute === 'function';
} Prevention
- Always build queries via drizzle(client).select().
- Inject the db into helpers instead of constructing QueryBuilder directly.
- Use toSQL() if you only need the SQL string.
When it happens
Trigger: Constructing a query with `new QueryBuilder()` and then calling .execute()/.prepare(); exporting a select builder without binding it to a db; passing a builder to a function that calls execute on it without a db.
Common situations: Trying to reuse query-construction helpers across modules by instantiating QueryBuilder directly; migrating from a raw SQL flow and forgetting to use the db instance; calling execute on a select returned from a test stub.
Related errors
- Cannot execute a query on a query builder. Please use a data
- Cannot execute a query on a query builder. Please use a data
- Your "${f.path.join('->')}" field references a column "${tab
- Your "${f.path.join('->')}" field references a column "${tab
- Your "${f.path.join('->')}" field references a column "${tab
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/e66931b7bd6e9bc1.json.
Report an issue: GitHub.