{"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/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/react-native/src/Statement.ts#L405-L441","documentation":"Statement.finalize() loops the native finalize call, servicing TursoStatus.IO by running runIo() and draining _extraIo; a non-DONE status throws with its numeric code (decode via TursoStatus: 4=BUSY, 127=ERROR, 128=MISUSE). Because this._finalized = true is only assigned after the loop breaks successfully, a throw here leaves the statement NOT marked finalized — finalize can be retried.","triggerScenarios":"Finalizing while the statement/database is BUSY (4) from another connection; pending sync IO that cannot complete during teardown (network gone while finalize needs to flush); native ERROR (127) during resource release.","commonSituations":"Closing a Database on app background while background sync still writes; finalizing inside an offline state where the IO drain cannot reach the sync server; teardown races at app exit.","solutions":["Decode the numeric status via the TursoStatus enum to identify the cause","Await outstanding statements/operations before closing, so finalize runs uncontended","Status 4 (BUSY): wait briefly and retry finalize() — it is safe to retry since _finalized was not set","Status 127/IO-related: verify connectivity during teardown or accept an unclean close and let recovery handle it"],"exampleFix":"// before\nawait stmt.finalize(); // throws during teardown: Statement finalization failed with status: 4\n\n// after\nasync function finalizeRetry(stmt, tries = 3) {\n  for (let i = 0; ; i++) {\n    try { return await stmt.finalize(); }\n    catch (e) {\n      if (i < tries - 1 && /status: 4$/.test(e.message)) {\n        await new Promise(r => setTimeout(r, 50));\n        continue;\n      }\n      throw e;\n    }\n  }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isFinalizeStatusError(e: unknown): boolean {\n  return e instanceof Error && /Statement finalization failed with status: \\d+/.test(e.message);\n}","tryCatchPattern":"async function finalizeSafely(stmt: Statement, tries = 3): Promise<void> {\n  for (let i = 0; ; i++) {\n    try { return await stmt.finalize(); }\n    catch (e) {\n      const busy = e instanceof Error && e.message.endsWith(`status: ${TursoStatus.BUSY}`);\n      if (i < tries - 1 && busy) {\n        await new Promise(r => setTimeout(r, 50 * (i + 1)));\n        continue; // safe: _finalized was not set on throw\n      }\n      throw e;\n    }\n  }\n}","preventionTips":["Quiesce outstanding operations before closing statements or the database","Remember finalize() is retryable when it throws — the flag is only set on success","Decode the status: BUSY(4) is retryable, ERROR(127) needs investigation"],"tags":["finalization","status-code","busy","react-native","sync"],"backgroundTag":"resource-cleanup-failed","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}