tursodatabase/turso · error · Error
getAllRows failed with status: ${bulk.status}
Error message
getAllRows failed with status: ${bulk.status} What it means
Statement.all() uses the native getAllRows bulk path. DONE returns the rows and IO is drained by calling _statement.runIo() plus the optional _extraIo callback; every other status hits this throw with its numeric code. The value decodes against the TursoStatus enum (4=BUSY, 127=ERROR, 128=MISUSE, 133=CORRUPT, 134=IOERR), and because this is a C++-side row scan, statuses often reflect storage or contention conditions discovered mid-scan.
Source
Thrown at bindings/react-native/src/Statement.ts:316
for (let ioRetries = 0; ioRetries < MAX_IO_RETRIES; ioRetries++) {
const bulk = this._statement.getAllRows();
if (bulk.rows && bulk.rows.length > 0) {
rows = rows.concat(bulk.rows);
}
if (bulk.status === TursoStatus.DONE) {
return rows;
}
if (bulk.status === TursoStatus.IO) {
this._statement.runIo();
if (this._extraIo) {
await this._extraIo();
}
continue;
}
throw new Error(`getAllRows failed with status: ${bulk.status}`);
}
throw new Error(`getAllRows: exceeded ${MAX_IO_RETRIES} IO retries`);
} finally {
this._statement.reset();
if (this._execLock) {
this._execLock.release();
}
}
}
/**
* Read current row into an object
*
* @returns Row object with column name keys
*/
private readRow(): Row {
const row: Row = {};View on GitHub (pinned to bad083fafb)
Solutions
- Decode the numeric status against the TursoStatus enum
- Status 4 (BUSY): retry after backoff or avoid concurrent write/read windows
- Status 133/134 (CORRUPT/IOERR): verify the database file, let sync re-download pages, check free space
- Status 128 (MISUSE): ensure reset()/bind() pairing on reused statements
Example fix
// before
const rows = await stmt.all(); // throws: getAllRows failed with status: 4
// after
async function allWithRetry(stmt, tries = 3) {
for (let i = 0; ; i++) {
try { return await stmt.all(); }
catch (e) {
const m = /status: (\d+)$/.exec(String(e.message));
if (i < tries - 1 && m && Number(m[1]) === 4 /* BUSY */) {
await new Promise(r => setTimeout(r, 50 * (i + 1)));
continue;
}
throw e;
}
}
} Defensive patterns
Strategy: try-catch
Type guard
function isStatusError(e: unknown, status: TursoStatus): boolean {
return e instanceof Error && e.message.endsWith(`status: ${status}`);
} Try / catch
try {
const rows = await stmt.all();
} catch (e) {
if (isStatusError(e, TursoStatus.BUSY)) {
await new Promise(r => setTimeout(r, 100));
return stmt.all(); // bounded retry
}
throw e; // CORRUPT/IOERR/MISUSE need investigation, not retry
} Prevention
- Decode the numeric status first; only BUSY is safely retryable
- Avoid large all() scans while background sync writes are in flight
- Watch for CORRUPT(133)/IOERR(134) — they indicate storage problems, not query bugs
When it happens
Trigger: A large SELECT via all() while another connection writes (BUSY 4); scanning pages that are corrupt or hit an IO error mid-bulk-read (133/134); MISUSE (128) when the statement state is invalid entering the bulk read.
Common situations: List screens running big all() queries during background sync writes; reading a partially-synced database whose local pages are incomplete (usually surfaces as IO first, but can degrade to ERROR); storage-level corruption after process kill.
Related errors
- Statement execution failed with status: ${result.status}
- Statement step failed with status: ${status}
- Statement finalization failed with status: ${status}
- push() is only available for sync databases
- pull() is only available for sync databases
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/7261481b2a918227.
Report an issue: GitHub.