tursodatabase/turso · error · DatabaseError
Batch execution failed
Error message
Batch execution failed
What it means
DatabaseError thrown from Session.batch() when a step of a batch fails on the server. In atomic mode the first error from BEGIN, any user step, or COMMIT is captured (deferredError) and re-thrown after the stream drains — so ROLLBACK and the trailing autocommit probe are still observed — while a fatal stream 'error' entry throws immediately. The literal text only appears for message-less errors.
Source
Thrown at serverless/javascript/src/session.ts:625
nextNonAtomicIdx = idx + 1;
}
currentResultIdx = undefined;
break;
}
case 'step_error':
// Capture the first error from BEGIN, any user step, or COMMIT
// and keep draining so the trailing probe (and, in atomic mode,
// ROLLBACK) is still observed. Errors on the synthetic ROLLBACK
// step are suppressed — by the time it runs the transaction has
// already been undone and surfacing a ROLLBACK error would mask
// the real cause we already captured.
if (deferredError === null && entry.step !== rollbackIdx) {
deferredError = new DatabaseError(entry.error?.message || 'Batch execution failed', entry.error?.code);
}
currentResultIdx = undefined;
break;
case 'error':
throw new DatabaseError(entry.error?.message || 'Batch execution failed', entry.error?.code);
}
}
if (deferredError !== null) {
throw deferredError;
}
return results;
}
/**
* Execute a sequence of SQL statements separated by semicolons.
*
* @param sql - SQL string containing multiple statements separated by semicolons
* @returns Promise resolving when all statements are executed
*/
async sequence(sql: string, queryOptions?: QueryOptions): Promise<void> {
const request: PipelineRequest = {View on GitHub (pinned to bad083fafb)
Solutions
- Identify the failing statement from the server message/code and fix it or its data (ON CONFLICT, pre-validation)
- Decide atomicity deliberately: pass a mode ('immediate', 'deferred', ...) for all-or-nothing, omit it when partial progress is acceptable
- For constraint-heavy bulk loads, pre-check uniqueness/FK validity or use INSERT OR IGNORE/REPLACE explicitly
Example fix
// before
await db.batch([
"INSERT INTO kv(k) VALUES ('a')",
"INSERT INTO kv(k) VALUES ('a')", // UNIQUE violation -> Batch execution failed, atomic mode rolls back
]);
// after
await db.batch([
"INSERT INTO kv(k) VALUES ('a')",
"INSERT INTO kv(k) VALUES ('a') ON CONFLICT(k) DO NOTHING",
], "immediate"); Defensive patterns
Strategy: try-catch
Type guard
const isDatabaseError = (e: unknown): e is Error & { code?: string } =>
e instanceof Error && e.name === "DatabaseError"; Try / catch
try {
await db.batch(statements, "immediate");
} catch (e) {
if (e instanceof Error && e.name === "DatabaseError") {
// atomic mode: nothing was committed — safe to fix and rerun the batch.
// non-atomic mode: earlier statements ARE committed — reconcile before rerun.
console.error("batch failed:", (e as { code?: string }).code, e.message);
}
throw e;
} Prevention
- Pass an explicit mode when you need all-or-nothing semantics; omit it only when partial progress is acceptable
- Add ON CONFLICT clauses for bulk loads that may contain duplicates
- Never mix transaction-control SQL (BEGIN/COMMIT/SAVEPOINT) into the statements array — it breaks the wrapper's atomicity contract
When it happens
Trigger: db.batch([...], 'immediate') where a mid-batch statement violates a constraint; any statement of a non-atomic batch failing; COMMIT itself failing in atomic mode (e.g. deferred foreign-key violations), after which earlier statements were rolled back.
Common situations: Bulk inserts hitting duplicate keys; batched migrations containing one bad statement; FK constraints enforced at COMMIT surprising 'atomic' batches; non-atomic batches leaving earlier statements committed after the failure (by design).
Related errors
- The supplied SQL string contains no statements
- Expected first argument to be an array of statements
- No active remote transaction
- Expected first argument to be a function
- transactionAsync is not supported with remoteWritesExperimen
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/6c5c897b6b243f85.
Report an issue: GitHub.