drizzle-team/drizzle-orm · error · DrizzleError

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

Error message

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

What it means

Thrown while building a nested relational query (db.query.X.findMany/findFirst with `with`/`columns` clauses) when the field selection for a given table resolves to zero columns. The relational mapper at dialect.ts:1347 requires every joined/selected table to contribute at least one field; an empty selection would produce invalid JSON building SQL. The names in the message are the TS table name and its alias.

Source

Thrown at drizzle-orm/src/pg-core/dialect.ts:1348

					on: sql`true`,
					table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias),
					alias: relationTableAlias,
					joinType: 'left',
					lateral: true,
				});
				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}")` });
		}

		let result;

		where = and(joinOn, where);

		if (nestedQueryRelation) {
			let field = sql`json_build_array(${
				sql.join(
					selection.map(({ field, tsKey, isJson }) =>
						isJson
							? sql`${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier('data')}`
							: is(field, SQL.Aliased)
							? field.sql
							: field
					),
					sql`, `,
				)

View on GitHub (pinned to b7862528fd)

Solutions

  1. Ensure every table/relation in the relational query selects at least one column (omit `columns` to select all, or list at least one).
  2. If the column list is dynamic, fall back to selecting the primary key or all columns when the computed list is empty.
  3. Review nested `with` blocks and `columns` filters for accidental empty objects.
  4. If you only need an aggregate, select it through `extras` alongside a real column or restructure the query.

Example fix

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

// after
await db.query.users.findMany({
  with: { posts: { columns: { id: true } } },
});
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every relation in a relational query selects >= 1 column.
function assertColumnsSelected(config: Record<string, any>) {
  for (const [rel, cfg] of Object.entries(config.with ?? {})) {
    if (cfg && 'columns' in cfg && cfg.columns !== undefined
        && Object.keys(cfg.columns).length === 0) {
      throw new Error(`Relation "${rel}" has no columns selected`);
    }
    if (cfg?.with) assertColumnsSelected(cfg);
  }
}
// run before db.query.X.findMany(config)

Type guard

function hasColumnsObject(cfg: unknown): cfg is { columns: Record<string, boolean> } {
  return typeof cfg === 'object' && cfg !== null
    && 'columns' in cfg && typeof (cfg as any).columns === 'object';
}

Prevention

When it happens

Trigger: Using the RQB relational API and filtering a nested relation's columns down to nothing — e.g. `db.query.users.findMany({ with: { posts: { columns: {} } } })`, or applying a `where`/`extras` combination that strips all columns. Also possible when a relation's referenced table has no selectable columns after a partial-column filter.

Common situations: Dynamically building a `columns` whitelist from user input and ending up with an empty object; migrating a findFirst config and accidentally leaving an empty `columns: {}`; misusing `with` on a relation while trying to fetch only an aggregate/count via `extras`.

Related errors


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