{"id":"873eb2b92f06e711","repo":"drizzle-team/drizzle-orm","slug":"insert-select-error-selected-fields-are-not-the-s-873eb2","errorCode":null,"errorMessage":"Insert select error: selected fields are not the same or are in a different order compared to the table definition","messagePattern":"Insert select error: selected fields are not the same or are in a different order compared to the table definition","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/pg-core/query-builders/insert.ts","lineNumber":128,"sourceCode":"\t}\n\n\tselect(selectQuery: (qb: QueryBuilder) => PgInsertSelectQueryBuilder<TTable>): PgInsertBase<TTable, TQueryResult>;\n\tselect(selectQuery: (qb: QueryBuilder) => SQL): PgInsertBase<TTable, TQueryResult>;\n\tselect(selectQuery: SQL): PgInsertBase<TTable, TQueryResult>;\n\tselect(selectQuery: PgInsertSelectQueryBuilder<TTable>): PgInsertBase<TTable, TQueryResult>;\n\tselect(\n\t\tselectQuery:\n\t\t\t| SQL\n\t\t\t| PgInsertSelectQueryBuilder<TTable>\n\t\t\t| ((qb: QueryBuilder) => PgInsertSelectQueryBuilder<TTable> | SQL),\n\t): PgInsertBase<TTable, TQueryResult> {\n\t\tconst select = typeof selectQuery === 'function' ? selectQuery(new QueryBuilder()) : selectQuery;\n\n\t\tif (\n\t\t\t!is(select, SQL)\n\t\t\t&& !haveSameKeys(this.table[Columns], select._.selectedFields)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'Insert select error: selected fields are not the same or are in a different order compared to the table definition',\n\t\t\t);\n\t\t}\n\n\t\treturn new PgInsertBase(this.table, select, this.session, this.dialect, this.withList, true);\n\t}\n}\n\nexport type PgInsertWithout<T extends AnyPgInsert, TDynamic extends boolean, K extends keyof T & string> =\n\tTDynamic extends true ? T\n\t\t: Omit<\n\t\t\tPgInsertBase<\n\t\t\t\tT['_']['table'],\n\t\t\t\tT['_']['queryResult'],\n\t\t\t\tT['_']['selectedFields'],\n\t\t\t\tT['_']['returning'],\n\t\t\t\tTDynamic,\n\t\t\t\tT['_']['excludedMethods'] | K","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/pg-core/query-builders/insert.ts#L110-L146","documentation":"PgInsertBuilder.select (insert.ts:116) validates an INSERT...SELECT via haveSameKeys, comparing the table's declared columns against the subquery's selectedFields. Because the columns must line up positionally and by name for a Postgres INSERT...SELECT, a mismatch in count, name, or order is rejected up front. Only raw SQL objects bypass this check.","triggerScenarios":"db.insert(t).select(qb => ...) where the inner select picks fewer/more columns, columns in a different order, or aliases that don't match the table's column keys. Also triggered by selecting computed/aliased fields instead of raw table columns.","commonSituations":"Copying rows between tables with similar but not identical schemas; selecting a subset of columns while intending to rely on defaults; reordering a select to match a changed table definition; forgetting that selectedFields keys must equal the destination column keys.","solutions":["Make the inner SELECT list exactly the destination table's columns in declaration order, keyed by the same names.","Prefer selecting the table object directly: qb.select().from(src) where src has identical columns, or map fields explicitly.","If you need a partial insert with defaults, use .values() instead of .select(), or build raw SQL to bypass the guard.","After schema changes, re-verify the column order of both source and destination."],"exampleFix":"// before\ndb.insert(dest).select(db.select({ id: src.id }).from(src)); // missing cols -> error\n\n// after\ndb.insert(dest).select(db.select({ id: src.id, name: src.name, email: src.email }).from(src)); // matches dest cols","handlingStrategy":"validation","validationCode":"import { getTableColumns } from 'drizzle-orm';\n\nconst srcColumns = Object.keys(getTableColumns(source)); // adjust to actual projection\nconst destColumns = Object.keys(getTableColumns(dest));\nif (srcColumns.length !== destColumns.length\n    || srcColumns.some((k, i) => k !== destColumns[i])) {\n  throw new Error('Source projection must match destination columns by name and order');\n}\nawait db.insert(dest).select(db.select().from(source));","typeGuard":"function sameKeys(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n  const ak = Object.keys(a), bk = Object.keys(b);\n  return ak.length === bk.length && ak.every((k, i) => k === bk[i]);\n}","tryCatchPattern":null,"preventionTips":["Mirror destination column order/name in the source projection.","Re-verify alignment after schema changes on either table.","Use raw SQL (sql\\`...\\`) only if you intentionally bypass the guard."],"tags":["insert","insert-select","schema","validation"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}