{"record":{"id":"9bf65606e9124363","repo":"tursodatabase/turso","slug":"statement-execution-failed-with-status-result-s","errorCode":null,"errorMessage":"Statement execution failed with status: ${result.status}","messagePattern":"Statement execution failed with status: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/react-native/src/Statement.ts","lineNumber":199,"sourceCode":"   */\n  private async executeWithIo(): Promise<{ status: number; rowsChanged: number }> {\n    while (true) {\n      const result = this._statement.execute();\n\n      if (result.status === TursoStatus.IO) {\n        // Statement needs IO (e.g., loading missing pages with partial sync)\n        this._statement.runIo();\n\n        // Drain sync engine IO queue\n        if (this._extraIo) {\n          await this._extraIo();\n        }\n\n        continue;\n      }\n\n      if (result.status !== TursoStatus.DONE) {\n        throw new Error(`Statement execution failed with status: ${result.status}`);\n      }\n\n      return result;\n    }\n  }\n\n  /**\n   * Step statement once handling potential IO (for partial sync)\n   * Matches Python's _step_once_with_io pattern\n   *\n   * @returns Status code\n   */\n  private async stepWithIo(): Promise<number> {\n    while (true) {\n      const status = this._statement.step();\n\n      if (status === TursoStatus.IO) {\n        // Statement needs IO (e.g., loading missing pages with partial sync)","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/react-native/src/Statement.ts#L181-L217","documentation":"Inside rawRun()'s executeWithIo loop, TursoStatus.IO (3) is handled by draining sync-engine IO, and any status other than TursoStatus.DONE (1) is rejected with its numeric code. The number maps to the TursoStatus enum in types.ts: 4=BUSY, 5=INTERRUPT, 127=ERROR, 128=MISUSE, 129=CONSTRAINT, 130=READONLY, 131=DATABASE_FULL, 132=NOTADB, 133=CORRUPT, 134=IOERR. The message is a raw number, so decoding it against the enum is the first diagnostic step.","triggerScenarios":"INSERT/UPDATE/DELETE through db.exec() or a Transaction that violates UNIQUE, NOT NULL, or a foreign key (status 129); writing to a read-only database (130); device storage exhausted mid-transaction (131); another connection holding the write lock (4); binding mismatches or reusing a misused statement (128).","commonSituations":"Duplicate-key inserts inside Transaction.run(); migrating code from better-sqlite3/libsql and expecting string error codes like 'SQLITE_CONSTRAINT' but getting 129; MVCC/multi-connection contention surfacing as 4; large sync writes filling device storage.","solutions":["Map the numeric status to the TursoStatus enum from '@tursodatabase/sync-react-native' to identify the real failure","Status 129 (CONSTRAINT): fix the data or add an ON CONFLICT clause / upsert to the SQL","Status 4 (BUSY): serialize writers or retry the operation after a short backoff","Status 130/131 (READONLY/DATABASE_FULL): check how the database was opened and free device storage","Status 128 (MISUSE): verify the number of bound parameters matches the statement's placeholders"],"exampleFix":"// before\nawait db.exec(stmt, [duplicateId]); // throws: Statement execution failed with status: 129\n\n// after\nconst fresh = db.prepare('INSERT INTO t(id) VALUES (?) ON CONFLICT(id) DO UPDATE SET id=excluded.id');\nawait db.exec(fresh, [duplicateId]);","handlingStrategy":"try-catch","validationCode":"import { TursoStatus } from '@tursodatabase/sync-react-native';\n\nfunction describeStatus(e: unknown): string | null {\n  const m = /status: (\\d+)$/.exec(e instanceof Error ? e.message : '');\n  return m ? TursoStatus[Number(m[1])] ?? `UNKNOWN(${m[1]})` : null;\n}","typeGuard":"function isStatusError(e: unknown, status: TursoStatus): boolean {\n  return e instanceof Error && e.message.endsWith(`status: ${status}`);\n}","tryCatchPattern":"try {\n  await db.exec(stmt, params);\n} catch (e) {\n  if (isStatusError(e, TursoStatus.BUSY)) {\n    await new Promise(r => setTimeout(r, 50));\n    return db.exec(stmt, params); // bounded retry\n  }\n  if (isStatusError(e, TursoStatus.CONSTRAINT)) {\n    // duplicate key etc. — surface a domain error, not a crash\n    throw new DuplicateKeyError(primaryKey);\n  }\n  throw e;\n}","preventionTips":["Keep the TursoStatus enum imported so numeric codes can be decoded at the catch site","Write UNIQUE-sensitive inserts as upserts (ON CONFLICT DO ...) when duplicates are expected","Serialize writers through a single queue to avoid BUSY contention","Validate bound parameter counts/types before exec to avoid MISUSE (128)"],"tags":["status-code","constraint-violation","busy","react-native","sync"],"backgroundTag":"sqlite-error-code","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}