drizzle-team/drizzle-orm · error · Error
Cannot pass undefined values to any set operator
Error message
Cannot pass undefined values to any set operator
What it means
Thrown by MySqlDialect.buildSetOperations (line 495) when destructuring setOperators yields undefined as the first element. This is a defensive internal invariant: a set operator entry was undefined/missing, which should not be reachable through the public API.
Source
Thrown at drizzle-orm/src/mysql-core/dialect.ts:495
const finalQuery =
sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${useIndexSql}${forceIndexSql}${ignoreIndexSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`;
if (setOperators.length > 0) {
return this.buildSetOperations(finalQuery, setOperators);
}
return finalQuery;
}
buildSetOperations(
leftSelect: SQL,
setOperators: MySqlSelectConfig['setOperators'],
): SQL {
const [setOperator, ...rest] = setOperators;
if (!setOperator) {
throw new Error('Cannot pass undefined values to any set operator');
}
if (rest.length === 0) {
return this.buildSetOperationQuery({ leftSelect, setOperator });
}
// Some recursive magic here
return this.buildSetOperations(
this.buildSetOperationQuery({ leftSelect, setOperator }),
rest,
);
}
buildSetOperationQuery({
leftSelect,
setOperator: { type, isAll, rightSelect, limit, orderBy, offset },
}: {
leftSelect: SQL;View on GitHub (pinned to b7862528fd)
Solutions
- Avoid manually pushing into query config.setOperators - use the .union()/.intersect()/.except() builder methods.
- Ensure you're not passing undefined to addSetOperators; filter out undefined entries first.
- If using a forked/patched Drizzle, diff against upstream set-operator handling.
- Upgrade to the latest Drizzle version in case this is a fixed internal regression.
Example fix
// before (advanced misuse)
(query as any).config.setOperators.push(undefined);
query.getSQL(); // throws
// after - only push valid operator objects
const op = { type: 'union', isAll: false, rightSelect: otherQuery };
(query as any).config.setOperators.push(op); Defensive patterns
Strategy: validation
Validate before calling
// Don't push undefined into config.setOperators const ops = candidateSetOperators.filter((o) => o != null) as NonNullable<typeof candidateSetOperators[number]>[]; if (ops.length === 0) return; // nothing to build query.addSetOperators(ops);
Type guard
function isSetOperator(v: unknown): v is MySqlSelectConfig['setOperators'][number] {
return v != null && typeof v === 'object' && 'type' in v && 'rightSelect' in v;
} Prevention
- Use the .union()/.intersect()/.except() builder methods, not manual config mutation.
- Filter undefined out of any array before passing to addSetOperators.
- Avoid monkey-patching Drizzle internals.
When it happens
Trigger: The setOperators array on MySqlSelectConfig contains an undefined entry before being built. Not normally reachable via db.select().union() since those validate inputs; would require manually mutating config.setOperators with undefined or an internal bug.
Common situations: Internal/advanced misuse where config.setOperators was patched to contain undefined; version mismatch or monkey-patching of Drizzle internals; extremely rare in normal usage.
Related errors
- Set operator error (union / intersect / except): selected fi
- Cannot pass undefined values to any set operator
- You have an empty array for "${name}" enum values
- values() must be called with at least one value
- Insert select error: selected fields are not the same or are
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/71a2f0717d7265e2.json.
Report an issue: GitHub.