{"record":{"id":"c5385315969dded9","repo":"tursodatabase/turso","slug":"expected-first-argument-to-be-an-array-of-statemen","errorCode":null,"errorMessage":"Expected first argument to be an array of statements","messagePattern":"Expected first argument to be an array of statements","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"bindings/javascript/packages/common/compat.ts","lineNumber":293,"sourceCode":"        if (stepResult === STEP_DONE) {\n          break;\n        }\n        if (stepResult === STEP_ROW) {\n          // For exec(), we don't need the row data, just continue\n          continue;\n        }\n      }\n    } finally {\n      exec.reset();\n    }\n  }\n\n  batch(\n    statements: Array<string | { sql: string; args?: any[] | Record<string, any> }>,\n    options?: BatchMode | BatchOptions,\n  ): ResultSet[] {\n    if (!Array.isArray(statements)) {\n      throw new TypeError(\"Expected first argument to be an array of statements\");\n    }\n    if (!this.open) {\n      throw new TypeError(\"The database connection is not open\");\n    }\n\n    const { mode, raw } = normalizeBatchOptions(options);\n    const wrap = mode != null && !this.db.inTransaction();\n    if (wrap) {\n      this.exec(`BEGIN ${normalizeBatchMode(mode!)}`);\n    }\n\n    const results: ResultSet[] = [];\n    try {\n      for (const statement of statements) {\n        const sql = typeof statement === \"string\" ? statement : statement.sql;\n        const args = typeof statement === \"string\" ? undefined : statement.args;\n        const stmt = this.db.prepare(sql);\n        try {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/javascript/packages/common/compat.ts#L275-L311","documentation":"Thrown by Database.batch() when the first argument is not an array. batch() expects an array of statements, each either a SQL string or an object { sql, args }, so passing a single statement, a variadic list, or a non-array (string, object, undefined) is rejected with this TypeError before any connection state is touched.","triggerScenarios":"Calling db.batch('INSERT INTO t VALUES (1)') with a bare string instead of an array; calling db.batch(stmt1, stmt2) expecting variadic behavior; passing a generator or Set of statements; passing undefined because a build step produced no statements.","commonSituations":"Migrating from an API that accepts a single statement; building statements conditionally and forgetting to wrap them in an array; converting from a Map/generator without Array.from; off-by-one refactors where the array literal is dropped.","solutions":["Wrap statements in an array: db.batch(['INSERT ...', { sql: 'UPDATE ...', args: [id] }])","Convert iterables explicitly: db.batch(Array.from(map.values()))","Guard dynamic statement lists: if (!Array.isArray(stmts) || stmts.length === 0) skip","Use a single prepare().run() when you only have one statement - batch is for groups"],"exampleFix":"// before\ndb.batch('DELETE FROM a; DELETE FROM b'); // single string -> TypeError\n\n// after\ndb.batch(['DELETE FROM a', 'DELETE FROM b']);","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(statements)) {\n  statements = [statements]; // or throw with context\n}\nif (statements.length === 0) return [];\ndb.batch(statements);","typeGuard":"type BatchStatement = string | { sql: string; args?: any[] | Record<string, any> };\nfunction isBatchInput(v: unknown): v is BatchStatement[] {\n  return Array.isArray(v) && v.every((s) => typeof s === 'string' || (s != null && typeof s === 'object' && typeof s.sql === 'string'));\n}","tryCatchPattern":null,"preventionTips":["Always construct batch input as an array literal, even for one statement","Convert iterables with Array.from before batching","Type the parameter as BatchStatement[] so TypeScript rejects bare strings"],"tags":["turso","javascript","batch","input-validation","better-sqlite3-compat"],"backgroundTag":"invalid-argument-type","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}