tursodatabase/turso · error · Error
Unexpected status from operation.resume()
Error message
Unexpected status from operation.resume(): ${status} What it means
driveOperation() loops operation.resume() and only two outcomes are progress: DONE (finished) and IO (needs IO, handled by processing the IO queue). Any other TursoStatus aborts with this error - it is the generic failure exit for every async sync operation (connect, pull, push, sync). The numeric status is the engine's reason; the true root cause is usually visible just before it, in a '[Turso HTTP] Request failed:' log or a poisoned IO item.
Solutions
- Map the number against TursoStatus (4=BUSY, 5=INTERRUPT, 6=BUSY_SNAPSHOT, 127=ERROR, 128=MISUSE, 130=READONLY, 133=CORRUPT, 134=IOERR) to narrow the cause
- Look for the console.error output from ioProcessor just before the throw - it names the failing URL/operation that poisoned the IO item
- Verify url/authToken in the connect options and device connectivity, then retry the operation on a fresh connection
- For CORRUPT/NOTADB-class causes, delete the local replica file and reconnect to re-bootstrap
Example fix
// before
await db.pull(); // 'Unexpected status from operation.resume(): 127'
// after - retry once on a fresh connection, surface root cause on repeat failure
async function pullWithRetry(db, opts) {
try {
return await db.pull();
} catch (e) {
console.warn('sync failed, reconnecting:', e.message);
await db.close();
const fresh = await connect(opts);
return fresh.pull();
}
} Defensive patterns
Strategy: retry
Validate before calling
// Cheap pre-flight: a sync round-trip exposes network/auth problems with a clear error
export async function assertSyncHealthy(db: Database): Promise<void> {
await db.sync();
} Try / catch
catch (e) { if (e instanceof Error && e.message.includes('operation.resume()')) { await db.close(); db = await connect(opts); return db.pull(); // one retry on a fresh connection } throw e; } Prevention
- Watch for '[Turso HTTP] Request failed:' console output - it names the root cause behind the opaque status number
- Keep a TursoStatus lookup table when handling sync errors (127=ERROR, 128=MISUSE, 133=CORRUPT, 134=IOERR)
- Validate url/authToken before connect so MISUSE-class statuses never start an operation
When it happens
Trigger: db.connect()/pull()/push()/sync() where the underlying native operation fails: a prior HTTP or file IO item was poisoned with an error (network fetch rejected, file read failed), the engine returned ERROR(127)/MISUSE(128)/BUSY(4), or arguments to the operation were invalid.
Common situations: Device offline or token rejected during a sync bootstrap; a corrupt local replica making the engine fail mid-operation; a custom file-system shim throwing; calling sync operations against a database opened purely locally by mistake.
Related errors
- HTTP request failed: . URL: , Method: , Body size: bytes
- checkpoint() is only available for sync databases
- GenericFailure
- getAllRows: exceeded
- HTTP request missing URL: no URL in request and no baseUrl…
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/6bd1624b1066e7c0.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/react-native/src/internal/asyncOperation.ts:77
default:
throw new Error(`Unknown result type: ${resultKind}`);
}
}
// Operation needs IO
if (status === TursoStatus.IO) {
// Process all pending IO items
await processIoQueue(database, context);
// Step callbacks after IO processing
database.ioStepCallbacks();
// Continue resume loop
continue;
}
// Any other status is an error
throw new Error(`Unexpected status from operation.resume(): ${status}`);
}
}
/**
* Process all pending IO items in the queue
*
* @param database - The native sync database
* @param context - IO context with auth and URL information
*/
async function processIoQueue(database: NativeSyncDatabase, context: IoContext): Promise<void> {
const promises: Promise<void>[] = [];
// Take all available IO items from the queue
while (true) {
const ioItem = database.ioTakeItem();
if (!ioItem) {
break; // No more items
}View on GitHub (pinned to 244cde92a7)