{"record":{"id":"309f6a1a6653576d","repo":"tursodatabase/turso","slug":"transactionasync-is-not-supported-with-remotewrite-309f6a","errorCode":null,"errorMessage":"transactionAsync is not supported with remoteWritesExperimental yet; use the deprecated transaction() for now","messagePattern":"transactionAsync is not supported with remoteWritesExperimental yet; use the deprecated transaction\\(\\) for now","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bindings/javascript/sync/packages/wasm/promise-default.ts","lineNumber":328,"sourceCode":"        Object.defineProperties(properties.immediate.value, properties);\n        Object.defineProperties(properties.exclusive.value, properties);\n        return properties.default.value as TransactionFunction<F>;\n    }\n\n    /**\n     * Returns a function that executes the given function in a transaction\n     * on a connection owned for the whole BEGIN..COMMIT window; the callback\n     * receives a {@link Transaction} handle as its first argument.\n     *\n     * Not supported together with {@link DatabaseOpts.remoteWritesExperimental}\n     * yet: remote-writes transactions run on the remote server and have no\n     * local connection to hand out.\n     */\n    override transactionAsync<F extends (txn: Transaction, ...args: any[]) => Promise<any>>(\n        fn: F,\n    ): AsyncTransactionFunction<F> {\n        if (this.#remoteWriter) {\n            throw new Error(\n                \"transactionAsync is not supported with remoteWritesExperimental yet; use the deprecated transaction() for now\",\n            );\n        }\n        return super.transactionAsync(fn);\n    }\n\n    /**\n     * close the database and relevant files\n     */\n    async close() {\n        if (this.#remoteWriter) {\n            await this.#remoteWriter.close();\n        }\n        if (this.#engine != null) {\n            if (this.name != null && this.#worker != null) {\n                const worker = this.#worker;\n                await Promise.all(this.#engine.filePaths().map((path: string) => unregisterFileAtWorker(worker, path)));\n            }","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/javascript/sync/packages/wasm/promise-default.ts#L310-L346","documentation":"transactionAsync hands the callback a Transaction handle bound to a local connection that is owned for the whole BEGIN..COMMIT window. When the database was constructed with remoteWritesExperimental, transactions execute on the remote server and there is no local connection to hand out, so the override throws rather than silently misbehave. The message points you to the deprecated transaction(), whose remote path wraps the entire callback in a remote BEGIN..COMMIT.","triggerScenarios":"new Database({ url, authToken, remoteWritesExperimental: true }) followed by db.transactionAsync((txn) => ...) — the remoteWriter being present is exactly what triggers the throw.","commonSituations":"Copying transactionAsync-based helpers from a local-connection codebase into a remoteWrites-enabled app; enabling the experimental flag during a migration and reusing existing transaction utilities; version upgrades where remoteWritesExperimental was newly introduced.","solutions":["Replace transactionAsync(fn) with transaction(fn); the remote writer wraps the whole callback remotely","Inside the callback, use the database handle (db.exec) instead of the per-connection txn handle","If you need the local Transaction handle, disable remoteWritesExperimental in DatabaseOpts","Centralize transaction creation in one adapter so the mode switch is a single code path"],"exampleFix":"// before\nconst run = db.transactionAsync(async (txn) => {\n  await txn.exec(\"INSERT INTO orders ...\");\n});\nawait run();\n\n// after (remoteWritesExperimental enabled)\nconst run = db.transaction(async () => {\n  await db.exec(\"INSERT INTO orders ...\");\n});\nawait run();","handlingStrategy":"validation","validationCode":"// Route at construction time: remoteWritesExperimental forbids transactionAsync\nconst remoteWrites = Boolean(opts.remoteWritesExperimental && opts.url);\nconst run = remoteWrites\n  ? db.transaction(fn)      // remote BEGIN..COMMIT wrapper\n  : db.transactionAsync(fn); // local connection handle\nawait run();","typeGuard":null,"tryCatchPattern":"try {\n  const run = db.transactionAsync(fn);\n  await run();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"remoteWritesExperimental\")) {\n    // fall back to the supported API\n    await db.transaction(fn)();\n  } else {\n    throw err;\n  }\n}","preventionTips":["Decide the transaction API once, based on the remoteWritesExperimental option, and use it everywhere","Do not copy transactionAsync call sites into remote-writes-enabled codebases","Wrap transaction creation in a single adapter so a mode switch cannot leave mixed call sites"],"tags":["transaction","remote-writes","experimental","sync","api-misuse"],"backgroundTag":"unsupported-feature-combination","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}