{"record":{"id":"4dc22fa1ac7ce091","repo":"tursodatabase/turso","slug":"database-must-be-connected-before-execution-the-fu","errorCode":null,"errorMessage":"database must be connected before execution the function","messagePattern":"database must be connected before execution the function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/javascript/packages/common/promise.ts","lineNumber":1158,"sourceCode":"        fn(result);\n        return result;\n      }\n    },\n    async resolve() {\n      if (promise != null) {\n        return await promise;\n      }\n      let valueResolve, valueReject;\n      promise = new Promise((resolve, reject) => {\n        valueResolve = x => { resolve(x); value = x; }\n        valueReject = reject;\n      });\n      await lazy().then(valueResolve, valueReject);\n      return await promise;\n    },\n    must() {\n      if (value == null) {\n        throw new Error(`database must be connected before execution the function`)\n      }\n      return value;\n    },\n  }\n}\n\nfunction maybeValue<T>(value: T): MaybeLazy<T> {\n  return {\n    apply(fn) { fn(value); },\n    resolve() { return Promise.resolve(value); },\n    must() { return value; },\n  }\n}\n\n/**\n * Statement represents a prepared SQL statement that can be executed.\n */\nclass Statement {","sourceCodeStart":1140,"sourceCodeEnd":1176,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/javascript/packages/common/promise.ts#L1140-L1176","documentation":"Internal guard in maybePromise.must() (common/promise.ts:994). When db.prepare() is called on a Database that has not connected yet, the returned Statement wraps a lazy chain (connect -> native prepare) and only materializes once that promise resolves. Synchronous accessors such as stmt.columns() and the stmt.reader getter call stmt.must(), which throws this error while the underlying value is still null - i.e. before the connection/prepare finished.","triggerScenarios":"Calling const stmt = db.prepare(sql) without awaiting, then immediately calling stmt.columns() or reading stmt.reader; using sync-style accessors on a lazily-connected (WASM/async IO) database; racing two operations where the connect promise has not settled yet; calling columns() inside a synchronous function that runs before the microtask queue flushes the connect+prepare chain.","commonSituations":"Porting sync API code (the compat API returns materialized statements) to the promise API where prepare returns a Promise-like Statement; framework code (e.g. a sync render path) touching stmt.columns() before an async effect completes; unit tests that forget to await the statement before introspecting columns.","solutions":["Await the statement before using sync accessors: const stmt = await db.prepare(sql); stmt.columns().","Or connect first: await db.connect(); then prepare - statements are materialized immediately (maybeValue path).","Keep column introspection inside async functions only; never read .columns()/.reader from sync callbacks.","In tests, make the prepare assertion async so the lazy chain settles before must() runs."],"exampleFix":"// before\nconst stmt = db.prepare(\"SELECT 1\"); // not awaited, db not connected yet\nstmt.columns(); // throws: database must be connected\n\n// after\nconst stmt = await db.prepare(\"SELECT 1\"); // connect + prepare settled\nstmt.columns();","handlingStrategy":"validation","validationCode":"const stmt = await db.prepare(sql); // resolves connect + native prepare\nstmt.columns(); // safe: statement materialized","typeGuard":null,"tryCatchPattern":"try {\n  stmt.columns();\n} catch (e) {\n  if (e instanceof Error && /must be connected/.test(e.message)) {\n    // lazy chain not settled: await the statement, then retry\n  } else throw e;\n}","preventionTips":["Always await the Statement returned by prepare before touching sync accessors (columns/reader).","Or await db.connect() once at startup so prepare is never lazy.","Never read .columns()/.reader from synchronous callbacks or render paths."],"tags":["lazy-initialization","connection","statement","columns","promise-api"],"backgroundTag":"database-not-connected","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}