tursodatabase/turso · error · DatabaseError
Sequence execution failed
Error message
Sequence execution failed
What it means
DatabaseError thrown when the server marks the first result of a sequence request as an error with no message — the literal 'Sequence execution failed' is the fallback; the server's own message is used when present. Sequences carry multi-statement SQL strings and back Connection.exec() and Transaction.exec(), so any failing statement in the script fails the whole call.
Source
Thrown at serverless/javascript/src/session.ts:670
try {
seqResponse = await executePipeline(this.httpContext(queryOptions), request, this.createAbortSignal(queryOptions));
} catch (e) {
this.baton = null;
this.autocommit = true;
throw e;
}
this.baton = seqResponse.baton;
if (seqResponse.base_url) {
this.baseUrl = normalizeUrl(seqResponse.base_url);
}
this.updateAutocommit(seqResponse);
// Check for errors in the response
if (seqResponse.results && seqResponse.results[0]) {
const result = seqResponse.results[0];
if (result.type === "error") {
throw new DatabaseError(result.error?.message || 'Sequence execution failed', result.error?.code);
}
}
}
/**
* Close the session.
*
* This sends a close request to the server to properly clean up the stream
* before resetting the local state.
*/
async close(): Promise<void> {
// Only send close request if we have an active baton
if (this.baton) {
try {
const request: PipelineRequest = {
baton: this.baton,
requests: [{
type: "close"View on GitHub (pinned to bad083fafb)
Solutions
- Split the script and run statements individually to isolate which one fails, then fix it per the server message
- Verify the script against the CLI before shipping (scripts/diff.sh or the shell)
- Wrap migrations in transactionAsync + tx.exec so a failed script rolls back instead of leaving partial DDL applied
Example fix
// before
await db.exec(readFileSync("schema.sql", "utf8")); // one bad statement fails the whole sequence
// after
for (const stmt of readFileSync("schema.sql", "utf8")
.split(";").map((s) => s.trim()).filter(Boolean)) {
await db.exec(stmt); // isolate and fix the failing statement
} 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.exec(script);
} catch (e) {
if (e instanceof Error && e.name === "DatabaseError") {
// split and run one statement at a time to identify the failing one
for (const stmt of script.split(";").map((s) => s.trim()).filter(Boolean)) {
await db.exec(stmt); // throws on the exact bad statement
}
} else throw e;
} Prevention
- Dry-run migration scripts against a copy of production before applying
- Run migrations inside transactionAsync + tx.exec so a failed script rolls back cleanly
- Lint dynamically built SQL to catch empty or malformed fragments before exec()
When it happens
Trigger: db.exec('CREATE TABLE ...; INSERT ...') where any statement in the script has a syntax error, references a missing object, or violates a constraint; Transaction.exec of migration scripts inside transactionAsync; dynamically joined SQL with a trailing malformed fragment.
Common situations: Applying schema migrations containing dialect-specific SQL the server rejects; seed scripts with constraint-violating rows; semicolon-joined statements built at runtime where one optional fragment is empty or malformed.
Related errors
- The supplied SQL string contains no statements
- Describe execution failed
- SQL execution failed
- Batch execution failed
- SQL execution failed
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/1dcbe18cb3a7dcbb.
Report an issue: GitHub.