drizzle-team/drizzle-orm · error · DrizzleError

No fields selected for table "${tableConfig.tsName}" ("${tab

Error message

No fields selected for table "${tableConfig.tsName}" ("${tableAlias}"). You need to have at least one item in "columns", "with" or "extras". If you need to select all columns, omit the "columns" key or set it to undefined.

What it means

Thrown by MySqlDialect.buildRelationalQueryWithoutLateralSubqueries (line 1225, non-lateral variant) when the computed selection is empty. Same condition as the lateral variant but for runtimes/configs that use the non-lateral relational query builder. The message is more explicit, listing columns/with/extras as the sources to populate.

Source

Thrown at drizzle-orm/src/mysql-core/dialect.ts:1225

				);
				let fieldSql = sql`(${builtRelation.sql})`;
				if (is(relation, Many)) {
					fieldSql = sql`coalesce(${fieldSql}, json_array())`;
				}
				const field = fieldSql.as(selectedRelationTsKey);
				selection.push({
					dbKey: selectedRelationTsKey,
					tsKey: selectedRelationTsKey,
					field,
					relationTableTsKey: relationTableTsName,
					isJson: true,
					selection: builtRelation.selection,
				});
			}
		}

		if (selection.length === 0) {
			throw new DrizzleError({
				message:
					`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}"). You need to have at least one item in "columns", "with" or "extras". If you need to select all columns, omit the "columns" key or set it to undefined.`,
			});
		}

		let result;

		where = and(joinOn, where);

		if (nestedQueryRelation) {
			let field = sql`json_array(${
				sql.join(
					selection.map(({ field }) =>
						is(field, MySqlColumn)
							? sql.identifier(this.casing.getColumnCasing(field))
							: is(field, SQL.Aliased)
							? field.sql
							: field

View on GitHub (pinned to b7862528fd)

Solutions

  1. Ensure at least one source of fields: set a column to true, add a `with` relation, or add an `extras` entry.
  2. Omit the columns key entirely (or set to undefined) to select all table columns.
  3. Validate dynamic column configs to guarantee at least one inclusion before querying.

Example fix

// before
db.query.posts.findMany({
  columns: { id: false, title: false, body: false },
});

// after - include at least one or omit
db.query.posts.findMany({ columns: { id: true } });
// or
 db.query.posts.findMany({});
Defensive patterns

Strategy: validation

Validate before calling

function validateRqbConfig(cfg: { columns?: Record<string, boolean>; with?: object; extras?: object }) {
  if (cfg.columns && Object.values(cfg.columns).every((v) => v === false)) {
    if (!cfg.with && !cfg.extras) throw new Error('RQB config selects nothing; add a column/with/extras');
  }
}

Type guard

function rqbHasFields(cfg: { columns?: Record<string, boolean>; with?: object; extras?: object }): boolean {
  if (!cfg.columns) return true;
  const v = Object.values(cfg.columns);
  return v.includes(true) || (v.some((x) => x === false) && !v.every((x) => x === false)) || Boolean(cfg.with) || Boolean(cfg.extras);
}

Prevention

When it happens

Trigger: db.query.X.findMany/findFirst with a columns object that excludes everything (all false) and no `with`/`extras`, executed on a path that uses the non-lateral relational builder.

Common situations: All-false columns object built dynamically; excluding all columns accidentally while intending to fetch only relations; refactor that emptied the selected columns.

Related errors


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