tursodatabase/turso · error · DatabaseError
SQL execution failed
Error message
SQL execution failed
What it means
Statement.iterate()'s async generator hit a step_error or error entry while streaming rows. Because the throw is inside the generator, it surfaces during `for await` iteration, not at the iterate() call itself. Unlike session.processCursorEntries, this site does not forward the server error code, so only the message distinguishes the failure.
Solutions
- Wrap the `for await` loop (not just the iterate() call) in try/catch
- Reproduce with all() to get the same failure with the server error code attached (session.ts forwards it, statement iterate does not)
- Fix the underlying SQL/schema problem named in the message
- Break out of the loop and let the generator's finally release the reader when abandoning early
Example fix
// before
const rows = stmt.iterate([category]);
for await (const row of rows) { handle(row); } // unhandled mid-stream throw
// after
try {
for await (const row of stmt.iterate([category])) { handle(row); }
} catch (e) {
if (e instanceof DatabaseError) { /* log e.message, fall back to stmt.all() */ }
throw e;
} Defensive patterns
Strategy: try-catch
Type guard
import { DatabaseError } from '@tursodatabase/serverless';
function isIterateError(e: unknown): e is DatabaseError {
return e instanceof DatabaseError && e.message === 'SQL execution failed';
} Try / catch
try {
for await (const row of stmt.iterate(args)) { process(row); }
} catch (e) {
// throws mid-iteration, not at iterate() — this try must wrap the loop
if (e instanceof DatabaseError) logAndRecover(e);
throw e;
} Prevention
- Always wrap the `for await` loop itself — the generator throws lazily during iteration
- This site does not forward error.code; during debugging use all() to get the code, then switch back to iterate()
- Break out of the loop explicitly when abandoning early so the generator's cleanup releases the stream reader
When it happens
Trigger: Iterating a statement whose execution fails server-side mid-stream (constraint violation on a RETURNING row, statement invalidated mid-iteration); malformed SQL that fails on the first entry; the underlying stream erroring after partial rows were already yielded.
Common situations: Streaming a large SELECT when the connection or stream breaks partway; iterating INSERT ... RETURNING where a later row violates a constraint; consuming the iterator after the session already errored.
Related errors
- Batch execution failed
- Describe execution failed
- Sequence execution failed
- SQL execution failed
- batch statement failed: is not allowed in an atomic batch
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/60f07f1b08c8129c.
Report an issue: GitHub.
Appendix: source
Thrown at serverless/javascript/src/statement.ts:298
}
break;
case 'row':
if (entry.row) {
const decodedRow = entry.row.map(value => decodeValue(value, this.safeIntegerMode));
if (this.presentationMode === 'pluck') {
// In pluck mode, yield only the first column value
yield decodedRow[0];
} else if (this.presentationMode === 'raw') {
// In raw mode, yield arrays of values
yield decodedRow;
} else {
yield createExpandedRow(decodedRow, columns);
}
}
break;
case 'step_error':
case 'error':
throw new DatabaseError(entry.error?.message || 'SQL execution failed');
}
}
}
}
View on GitHub (pinned to 244cde92a7)