{"id":"92c071a33c133b5d","repo":"drizzle-team/drizzle-orm","slug":"cannot-pass-undefined-values-to-any-set-operator-92c071","errorCode":null,"errorMessage":"Cannot pass undefined values to any set operator","messagePattern":"Cannot pass undefined values to any set operator","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/pg-core/dialect.ts","lineNumber":454,"sourceCode":"\t\t\t\tclauseSql.append(sql` skip locked`);\n\t\t\t}\n\t\t\tlockingClauseSql.append(clauseSql);\n\t\t}\n\t\tconst finalQuery =\n\t\t\tsql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClauseSql}`;\n\n\t\tif (setOperators.length > 0) {\n\t\t\treturn this.buildSetOperations(finalQuery, setOperators);\n\t\t}\n\n\t\treturn finalQuery;\n\t}\n\n\tbuildSetOperations(leftSelect: SQL, setOperators: PgSelectConfig['setOperators']): SQL {\n\t\tconst [setOperator, ...rest] = setOperators;\n\n\t\tif (!setOperator) {\n\t\t\tthrow new Error('Cannot pass undefined values to any set operator');\n\t\t}\n\n\t\tif (rest.length === 0) {\n\t\t\treturn this.buildSetOperationQuery({ leftSelect, setOperator });\n\t\t}\n\n\t\t// Some recursive magic here\n\t\treturn this.buildSetOperations(\n\t\t\tthis.buildSetOperationQuery({ leftSelect, setOperator }),\n\t\t\trest,\n\t\t);\n\t}\n\n\tbuildSetOperationQuery({\n\t\tleftSelect,\n\t\tsetOperator: { type, isAll, rightSelect, limit, orderBy, offset },\n\t}: { leftSelect: SQL; setOperator: PgSelectConfig['setOperators'][number] }): SQL {\n\t\tconst leftChunk = sql`(${leftSelect.getSQL()}) `;","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/pg-core/dialect.ts#L436-L472","documentation":"Thrown by PgDialect.buildSetOperations when the first element of the setOperators array destructured at dialect.ts:451 is undefined. The dialect can only compose UNION/INTERSECT/EXCEPT from concrete operator descriptors; an undefined entry indicates the query builder state was corrupted or an internal API was misused. It is primarily a defensive guard against malformed internal state rather than a user-facing API contract.","triggerScenarios":"Produced only when PgSelect.addSetOperators (or a direct dialect call) pushes/derives a setOperators array whose first element is undefined — e.g. calling a set-operator method with an undefined right-hand select, or a custom fork that passes a sparse array to buildSetOperations. Calling .union(undefined) or programmatically appending an undefined operator object can surface it.","commonSituations":"Almost never seen with the stock public API because createSetOperator and the chainable helpers validate selections first. Encountered mainly in internal/tooling code, monkeypatched builds, or when a dynamic array of selects contains a hole. May appear after a refactor that conditionally pushes operators (push(cond ? op : undefined)).","solutions":["Inspect the array passed to the set-operator chain; ensure every element is a concrete select and never undefined.","If building operators dynamically, filter out falsy entries before calling union/unionAll/intersect/except: selects.filter(Boolean).","Avoid calling set-operator helpers with sparse arrays or conditional undefined operands; guard the call site.","If you hit this without custom code, check for a drizzle-orm version mismatch where the query builder state is partially initialized."],"exampleFix":"// before\nconst ops = [a, cond ? b : undefined];\ndb.select().from(t).union(ops[0]).union(ops[1]); // hole -> undefined\n\n// after\nconst ops = [a, cond ? b : b2].filter(Boolean);\ndb.select().from(t).union(ops[0]).union(ops[1]);","handlingStrategy":"validation","validationCode":"// Before chaining set operators, ensure every operand is a defined select.\nconst branches = [leftSelect, ...rightSelects].filter(\n  (s): s is AnyPgSelect => s != null && typeof s.getSelectedFields === 'function',\n);\nif (branches.length < 2) {\n  throw new Error('Set operator requires at least two valid selects');\n}\nconst result = union(branches[0], branches[1], ...branches.slice(2));","typeGuard":"import { is, TypedQueryBuilder } from 'drizzle-orm';\n\nfunction isValidSelect(s: unknown): s is TypedQueryBuilder<any, any> {\n  return s != null && typeof s === 'object'\n    && typeof (s as any).getSelectedFields === 'function';\n}","tryCatchPattern":null,"preventionTips":["Filter falsy/undefined entries out of dynamic set-operator arrays before use.","Never push conditionally-undefined operators into a setOperators array.","Treat this error as a signal of corrupted builder state; audit custom forks."],"tags":["set-operators","internal","validation"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}