drizzle-team/drizzle-orm · error · Error
Set operator error (union / intersect / except): selected fi
Error message
Set operator error (union / intersect / except): selected fields are not the same or are in a different order
What it means
Thrown by createSetOperator on the select builder (line 570) when a chained set operator (union/unionAll/intersect/intersectAll/except/exceptAll) is added and the right select's fields don't match the left select's fields (keys + order via haveSameKeys). Set operations require both sides to project the same shape.
Source
Thrown at drizzle-orm/src/mysql-core/query-builders/select.ts:570
rightSelection:
| ((setOperators: GetMySqlSetOperators) => SetOperatorRightSelect<TValue, TResult>)
| SetOperatorRightSelect<TValue, TResult>,
) => MySqlSelectWithout<
this,
TDynamic,
MySqlSetOperatorExcludedMethods,
true
> {
return (rightSelection) => {
const rightSelect = (typeof rightSelection === 'function'
? rightSelection(getMySqlSetOperators())
: rightSelection) as TypedQueryBuilder<
any,
TResult
>;
if (!haveSameKeys(this.getSelectedFields(), rightSelect.getSelectedFields())) {
throw new Error(
'Set operator error (union / intersect / except): selected fields are not the same or are in a different order',
);
}
this.config.setOperators.push({ type, isAll, rightSelect });
return this as any;
};
}
/**
* Adds `union` set operator to the query.
*
* Calling this method will combine the result sets of the `select` statements and remove any duplicate rows that appear across them.
*
* See docs: {@link https://orm.drizzle.team/docs/set-operations#union}
*
* @example
*View on GitHub (pinned to b7862528fd)
Solutions
- Make both selects project identical keys in the same order.
- Alias fields on both sides so the key sets match exactly.
- If you need different shapes, combine them with a different query strategy (e.g. client-side merge).
- Double-check that aliased columns use the same alias key on both sides.
Example fix
// before
db.select({ id: users.id, name: users.name }).from(users)
.union(db.select({ id: customers.id, email: customers.email }).from(customers));
// keys {id,name} vs {id,email} => throws
// after - align shapes
db.select({ id: users.id, label: users.name }).from(users)
.union(db.select({ id: customers.id, label: customers.email }).from(customers)); Defensive patterns
Strategy: validation
Validate before calling
import { haveSameKeys } from '~/utils.ts';
if (!haveSameKeys(left.getSelectedFields(), right.getSelectedFields())) {
throw new Error('Set-operator sides must select the same keys in the same order');
} Type guard
function shapesMatch(a: { getSelectedFields(): Record<string, unknown> }, b: { getSelectedFields(): Record<string, unknown> }): boolean {
return haveSameKeys(a.getSelectedFields(), b.getSelectedFields());
} Prevention
- Project identical keys in the same order on both sides of a set operator.
- Use consistent aliases across all operands.
- Re-check shapes after refactoring any select used in a union/intersect/except.
When it happens
Trigger: db.select({ a, b }).from(t1).union(db.select({ a, c }).from(t2)) - different keys or order. The method-style operator validates against this.getSelectedFields() vs rightSelect.getSelectedFields().
Common situations: Different columns selected on each side; same columns in different order; one side aliased differently; refactored one select but not the other.
Related errors
- Set operator error (union / intersect / except): selected fi
- Cannot pass undefined values to any set operator
- Alias "${tableName}" is already used in this query
- Cannot pass undefined values to any set operator
- Cannot pass undefined values to any set operator
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/c9224c11b9d4a032.json.
Report an issue: GitHub.