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 while building a nested relational (with/relations) selection (dialect.ts:827) when a table's config object has empty columns, with, AND extras — i.e. nothing to select for that table. Drizzle needs at least one selected item per table in a relational query; an all-empty config is treated as a user error. To select every column you should omit the columns key (or set it to undefined) rather than pass an empty object.

Source

Thrown at drizzle-orm/src/sqlite-core/dialect.ts:827

						: selectedRelationConfigValue,
					tableAlias: relationTableAlias,
					joinOn,
					nestedQueryRelation: relation,
				});
				const field = sql`(${builtRelation.sql})`.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, SQLiteColumn)
							? sql.identifier(this.casing.getColumnCasing(field))
							: is(field, SQL.Aliased)
							? field.sql
							: field

View on GitHub (pinned to b7862528fd)

Solutions

  1. If you want all columns: omit the columns key entirely (or set columns: undefined).
  2. If selecting a subset: ensure at least one column key is set to true.
  3. Add a with or extras entry if you intentionally select no base columns but want relation/extra fields.

Example fix

// before
await db.query.users.findMany({
  with: { posts: { columns: {} } }, // empty object -> throws
});

// after — select all post columns
await db.query.users.findMany({
  with: { posts: true },
});
// or a subset
await db.query.users.findMany({
  with: { posts: { columns: { id: true, title: true } } },
});
Defensive patterns

Strategy: validation

Validate before calling

function normaliseColumns(config) {
  // treat {} as 'select all'
  if (config && 'columns' in config && config.columns !== undefined
      && Object.keys(config.columns).length === 0) {
    const { columns, ...rest } = config;
    return { ...rest, columns: undefined };
  }
  return config;
}

Type guard

const hasSelectableFields = (cfg) =>
  (cfg.columns && Object.keys(cfg.columns).length > 0)
  || (cfg.with && Object.keys(cfg.with).length > 0)
  || (cfg.extras && Object.keys(cfg.extras).length > 0);

Prevention

When it happens

Trigger: Calling a nested relation with { columns: {} } (explicit empty object) and no with/extras; passing a config where columns was set to {} by a transform that removed all keys. Setting columns to undefined (select-all) does NOT throw — only an explicit empty object does.

Common situations: Programmatically building a 'columns to select' object from a whitelist that came back empty; copy-pasting a relational query and deleting the columns key contents; a serializer that strips keys and leaves {}.

Related errors


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