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 in SingleStoreSelectBase.prepare (select.ts:992) when this.session is undefined. A select built via the query-builder factory ($drizzle.createQueryBuilder() / SingleStoreSelectBuilder without a session) has no database connection and therefore cannot be prepared or executed; only a SingleStoreDatabase instance (db.select(...)) carries a session.
Source
Thrown at drizzle-orm/src/singlestore-core/query-builders/select.ts:992
TResult = SelectResult<TSelection, TSelectMode, TNullabilityMap>[],
TSelectedFields = BuildSubquerySelection<TSelection, TNullabilityMap>,
> extends SingleStoreSelectQueryBuilderBase<
SingleStoreSelectHKT,
TTableName,
TSelection,
TSelectMode,
TPreparedQueryHKT,
TNullabilityMap,
TDynamic,
TExcludedMethods,
TResult,
TSelectedFields
> {
static override readonly [entityKind]: string = 'SingleStoreSelect';
prepare(): SingleStoreSelectPrepare<this> {
if (!this.session) {
throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.');
}
const fieldsList = orderSelectedFields<SingleStoreColumn>(this.config.fields);
const query = this.session.prepareQuery<
SingleStorePreparedQueryConfig & { 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 SingleStoreSelectPrepare<this>;
}
$withCache(config?: { config?: CacheConfig; tag?: string; autoInvalidate?: boolean } | false) {
this.cacheConfig = config === undefined
? { config: {}, enable: true, autoInvalidate: true }
: config === false
? { enable: false }View on GitHub (pinned to b7862528fd)
Solutions
- Use the database instance to build executable queries: `db.select(...).from(...)` instead of `qb.select(...)`.
- If you only need the SQL string from a builder, call .toSQL() (which does not require a session).
- Pass the db (or tx) into the function that needs to execute, not the bare query builder.
Example fix
// before
const qb = db.$with('qb');
const q = db.select({id: users.id}).from(users); // built from qb w/o session
await q.execute();
// after
const q = db.select({id: users.id}).from(users);
await q.execute(); Defensive patterns
Strategy: type-guard
Validate before calling
function isExecutable(select) {
return Boolean(select.session);
}
if (!isExecutable(q)) throw new Error('Use db.select(), not a session-less query builder, to execute'); Type guard
function isRunnableSelect(q): boolean {
return Boolean(q && q.session);
} Prevention
- Build executable selects from the db (or tx) instance, not createQueryBuilder.
- Use .toSQL() when you only need SQL text from a builder.
- Pass db/tx into functions that need to execute queries.
When it happens
Trigger: Calling .execute(), .prepare(), or .iterator() on a select created via createQueryBuilder (the 'qb' builder mode) instead of via the db instance; passing a builder around and trying to run it directly.
Common situations: Using drizzle's query-builder API to compose SQL for inspection but accidentally calling execute on it; refactoring db access into a layer that receives a qb instead of db; confusing the query-builder (composition only) with the database (execution).
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
- Cannot execute a query on a query builder. Please use a data
- 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/824690a1fe42c89d.json.
Report an issue: GitHub.