{"id":"0441743b2713a7e9","repo":"drizzle-team/drizzle-orm","slug":"values-must-be-called-with-at-least-one-value-044174","errorCode":null,"errorMessage":"values() must be called with at least one value","messagePattern":"values\\(\\) must be called with at least one value","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/sqlite-core/query-builders/insert.ts","lineNumber":61,"sourceCode":"\tTRunResult,\n> {\n\tstatic readonly [entityKind]: string = 'SQLiteInsertBuilder';\n\n\tconstructor(\n\t\tprotected table: TTable,\n\t\tprotected session: SQLiteSession<any, any, any, any>,\n\t\tprotected dialect: SQLiteDialect,\n\t\tprivate withList?: Subquery[],\n\t) {}\n\n\tvalues(value: SQLiteInsertValue<TTable>): SQLiteInsertBase<TTable, TResultType, TRunResult>;\n\tvalues(values: SQLiteInsertValue<TTable>[]): SQLiteInsertBase<TTable, TResultType, TRunResult>;\n\tvalues(\n\t\tvalues: SQLiteInsertValue<TTable> | SQLiteInsertValue<TTable>[],\n\t): SQLiteInsertBase<TTable, TResultType, TRunResult> {\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\t// if (mappedValues.length > 1 && mappedValues.some((t) => Object.keys(t).length === 0)) {\n\t\t// \tthrow new Error(\n\t\t// \t\t`One of the values you want to insert is empty. In SQLite you can insert only one empty object per statement. For this case Drizzle with use \"INSERT INTO ... DEFAULT VALUES\" syntax`,\n\t\t// \t);\n\t\t// }\n\n\t\treturn new SQLiteInsertBase(this.table, mappedValues, this.session, this.dialect, this.withList);","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/sqlite-core/query-builders/insert.ts#L43-L79","documentation":"Thrown by SQLiteInsertBuilder.values() (insert.ts:61) when the values argument — after normalisation to an array — has length zero. SQLite cannot insert nothing, and drizzle treats an empty values call as a programming error rather than emit a no-op statement.","triggerScenarios":"Calling db.insert(t).values([]) directly; passing an array variable that was filtered down to zero items; spreading a batch array that resolved to []. Passing a single object never triggers it; only an empty array does.","commonSituations":"Batch insert from a list that the caller did not pre-size; an empty CSV import; a 'sync' routine that has nothing to insert this run; debounced bulk insert with no incoming rows.","solutions":["Guard the call: if (rows.length) await db.insert(t).values(rows);","Short-circuit empty batches at the service layer and return early.","Log when a batch is unexpectedly empty to surface upstream bugs."],"exampleFix":"// before\nawait db.insert(users).values(batch); // throws if batch === []\n\n// after\nif (batch.length > 0) {\n  await db.insert(users).values(batch);\n}","handlingStrategy":"validation","validationCode":"async function safeInsert(db, table, rows) {\n  if (!rows.length) return { rowsInserted: 0 };\n  return db.insert(table).values(rows);\n}","typeGuard":"const isNonEmpty = <T>(a: T[]): a is [T, ...T[]] => a.length > 0;","tryCatchPattern":null,"preventionTips":["Always size-check batch arrays before .values().","Return early from sync/import routines when there is nothing to insert.","Log empty batches to surface upstream data issues."],"tags":["insert","validation","batch"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}