{"record":{"id":"f7e766ae870b3755","repo":"tursodatabase/turso","slug":"statement-finalization-failed-with-status-statu","errorCode":null,"errorMessage":"Statement finalization failed with status: ${status}","messagePattern":"Statement finalization failed with status: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/react-native/src/Statement.ts","lineNumber":423,"sourceCode":"    }\n    try {\n      while (true) {\n        const status = this._statement.finalize();\n\n        if (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 (status !== TursoStatus.DONE) {\n          throw new Error(`Statement finalization failed with status: ${status}`);\n        }\n        break;\n      }\n      this._finalized = true;\n    } finally {\n      if (this._execLock) {\n        this._execLock.release();\n      }\n    }\n  }\n\n  /**\n   * Check if statement has been finalized\n   */\n  get finalized(): boolean {\n    return this._finalized;\n  }\n}","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/react-native/src/Statement.ts#L405-L441","documentation":"Statement.finalize() loops the native finalize() call, handling IO (partial-sync page loads) along the way, and expects DONE. Any other TursoStatus - BUSY(4), INTERRUPT(5), BUSY_SNAPSHOT(6), ERROR(127), MISUSE(128), CONSTRAINT(129), READONLY(130), DATABASE_FULL(131), NOTADB(132), CORRUPT(133), IOERR(134) - aborts with this error. The number in the message is the engine's raw status code for why the statement could not be finalized cleanly.","triggerScenarios":"await stmt.finalize() while the underlying database is in a bad state: CORRUPT/NOTADB from a damaged local file, IOERR from a failing file layer (custom setFileSystemImpl that throws), MISUSE from double-finalization at the native level, or DATABASE_FULL on a full disk.","commonSituations":"App killed mid-write leaving a corrupt local replica; a custom file-system implementation (encryption/compression shim) that raises during the final flush; device storage exhausted; finalizing inside error-recovery code that runs while the connection is already broken.","solutions":["Decode the numeric status against the TursoStatus enum (e.g. 133=CORRUPT, 134=IOERR, 131=DATABASE_FULL) to find the root cause","If you pass setFileSystemImpl, make sure your read/write shims never reject - a throw here surfaces as IOERR on finalize","For CORRUPT/NOTADB, delete the local replica file and re-connect to re-bootstrap from the remote","Free device storage if DATABASE_FULL; otherwise close and recreate the Database and prepare fresh statements"],"exampleFix":"// before\nawait stmt.finalize(); // throws 'Statement finalization failed with status: 133'\n\n// after - decode status and recover the replica\ntry {\n  await stmt.finalize();\n} catch (e) {\n  const status = Number(e.message.match(/status: (\\d+)/)?.[1]);\n  if (status === 133 /* CORRUPT */ || status === 132 /* NOTADB */) {\n    await db.close();\n    await RNFS.unlink(dbPath); // drop damaged replica\n    db = await connect(opts);  // re-bootstrap from remote\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await stmt.finalize(); } catch (e) { const m = e.message.match(/status: (\\d+)/); const status = m ? Number(m[1]) : null; // 133=CORRUPT,132=NOTADB -> drop replica and re-bootstrap; 131 -> free storage; else rethrow }","preventionTips":["Keep the TursoStatus code table (4=BUSY..134=IOERR) next to your error handling so numbers decode fast","If you install setFileSystemImpl, make the shims swallow/retry their own errors - a throw surfaces here as IOERR","Monitor free disk space on Android/iOS before large write transactions to avoid DATABASE_FULL at finalize"],"tags":["react-native","statement-lifecycle","native-status","recovery"],"backgroundTag":"statement-finalize-failed","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}