{"id":"b46bc6681a36d476","repo":"drizzle-team/drizzle-orm","slug":"values-must-be-called-with-at-least-one-value-b46bc6","errorCode":null,"errorMessage":"values() must be called with at least one value","messagePattern":"values\\(\\) must be called with at least one value","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/mysql-core/query-builders/insert.ts","lineNumber":76,"sourceCode":"\tconstructor(\n\t\tprivate table: TTable,\n\t\tprivate session: MySqlSession,\n\t\tprivate dialect: MySqlDialect,\n\t) {}\n\n\tignore(): this {\n\t\tthis.shouldIgnore = true;\n\t\treturn this;\n\t}\n\n\tvalues(value: MySqlInsertValue<TTable>): MySqlInsertBase<TTable, TQueryResult, TPreparedQueryHKT>;\n\tvalues(values: MySqlInsertValue<TTable>[]): MySqlInsertBase<TTable, TQueryResult, TPreparedQueryHKT>;\n\tvalues(\n\t\tvalues: MySqlInsertValue<TTable> | MySqlInsertValue<TTable>[],\n\t): MySqlInsertBase<TTable, TQueryResult, TPreparedQueryHKT> {\n\t\tvalues = Array.isArray(values) ? values : [values];\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('values() must be called with at least one value');\n\t\t}\n\t\tconst mappedValues = values.map((entry) => {\n\t\t\tconst result: Record<string, Param | SQL> = {};\n\t\t\tconst cols = this.table[Table.Symbol.Columns];\n\t\t\tfor (const colKey of Object.keys(entry)) {\n\t\t\t\tconst colValue = entry[colKey as keyof typeof entry];\n\t\t\t\tresult[colKey] = is(colValue, SQL) ? colValue : new Param(colValue, cols[colKey]);\n\t\t\t}\n\t\t\treturn result;\n\t\t});\n\n\t\treturn new MySqlInsertBase(this.table, mappedValues, this.shouldIgnore, this.session, this.dialect);\n\t}\n\n\tselect(\n\t\tselectQuery: (qb: QueryBuilder) => MySqlInsertSelectQueryBuilder<TTable>,\n\t): MySqlInsertBase<TTable, TQueryResult, TPreparedQueryHKT>;\n\tselect(selectQuery: (qb: QueryBuilder) => SQL): MySqlInsertBase<TTable, TQueryResult, TPreparedQueryHKT>;","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/mysql-core/query-builders/insert.ts#L58-L94","documentation":"Thrown by MySqlInsertBuilder.values (line 76) when the values argument resolves to an empty array. MySQL INSERT VALUES requires at least one row; Drizzle fails fast at query construction rather than emitting invalid SQL.","triggerScenarios":"Calling db.insert(table).values([]) directly, or passing an array variable that happens to be empty at runtime (e.g. a bulk-insert loop with no items).","commonSituations":"Batch insert where the source array is empty due to upstream filtering; processing user-uploaded rows that yielded zero records; forgetting to guard an array before insert.","solutions":["Guard before calling values: if (rows.length) await db.insert(table).values(rows);","Ensure the source array is populated; log its length if inserts are unexpectedly empty.","Skip the insert entirely when there's nothing to insert rather than relying on the error."],"exampleFix":"// before\nconst rows = pendingOrders.filter(o => o.ready); // []\nawait db.insert(orders).values(rows); // throws\n\n// after - skip when empty\nconst rows = pendingOrders.filter(o => o.ready);\nif (rows.length > 0) {\n  await db.insert(orders).values(rows);\n}","handlingStrategy":"validation","validationCode":"if (!Array.isArray(rows) || rows.length === 0) {\n  // nothing to insert; skip\n  return;\n}\nawait db.insert(table).values(rows);","typeGuard":"function hasRows<T>(rows: T[]): rows is [T, ...T[]] {\n  return rows.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Guard bulk inserts with if (rows.length > 0).","Validate source arrays before constructing the insert.","Skip no-op inserts rather than catching the error."],"tags":["mysql","insert","validation","query-builder"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}