tursodatabase/turso · error · TypeError

Expected first argument to be an array of statements

Error message

Expected first argument to be an array of statements

What it means

batch() requires its first argument to be an array of InStatement; anything else - a single statement object, a bare string, varargs, or undefined - throws this TypeError. Note the throw happens inside batch()'s try block, so the compat layer's catch wraps it into a BATCH_ERROR LibsqlError with the TypeError as the cause; the message still tells you the shape of the argument was wrong.

Solutions

  1. Always pass an array: client.batch([stmt1, stmt2]) or client.batch([sqlString])
  2. For a single statement, use client.execute(stmt) instead
  3. Check Array.isArray(stmts) before calling batch in code that assembles statements dynamically
  4. Inspect error.cause if you caught a BATCH_ERROR - the TypeError inside identifies this case

Example fix

// before
await client.batch({ sql: 'UPDATE t SET x = 1' }); // not an array
await client.batch(stmt1, stmt2);               // varargs are not supported

// after
await client.batch([{ sql: 'UPDATE t SET x = 1' }]);
await client.batch([stmt1, stmt2]);
Defensive patterns

Strategy: validation

Validate before calling

function toBatchArg(stmts: InStatement | InStatement[] | undefined): InStatement[] {
  if (stmts === undefined) return [];
  return Array.isArray(stmts) ? stmts : [stmts];
}
await client.batch(toBatchArg(maybeSingleStmt));

Type guard

function isStatementArray(v: unknown): v is Array<InStatement> {
  return Array.isArray(v);
}

Prevention

When it happens

Trigger: client.batch(stmt) with a single statement instead of client.batch([stmt]); calling batch(s1, s2) as if it were variadic; passing a value that is undefined because a builder function forgot to return its array.

Common situations: Porting code from an API that took varargs or a single statement; conditional statement lists where the array variable ends up undefined; refactors that return undefined from a statements-builder helper.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20). Data as JSON: /api/errors/1ed6b2d50d8edac1. Report an issue: GitHub.

Appendix: source

Thrown at serverless/javascript/src/compat.ts:339

    } catch (error: any) {
      if (error instanceof LibsqlError) {
        throw error;
      }
      throw mapDatabaseError(error, "EXECUTE_ERROR");
    } finally {
      this.execLock.release();
    }
  }

  async batch(stmts: Array<InStatement>, options?: TransactionMode | BatchOptions): Promise<Array<BatchResultSet>> {
    await this.execLock.acquire();
    try {
      if (this._closed) {
        throw new LibsqlError("Client is closed", "CLIENT_CLOSED");
      }

      if (!Array.isArray(stmts)) {
        throw new TypeError("Expected first argument to be an array of statements");
      }

      const { mode, raw } = this.normalizeBatchOptions(options);
      const batchMode = mode ?? "deferred";

      const results = await this.session.batch(
        stmts,
        batchMode,
        undefined,
        this._defaultSafeIntegers,
        raw,
      );

      return results.map((result: any) => this.convertBatchResult(result));
    } catch (error: any) {
      if (error instanceof LibsqlError) {
        throw error;
      }

View on GitHub (pinned to 6c72522679)