tursodatabase/turso · error · Error
transactionAsync is not supported with remoteWritesExperimen
Error message
transactionAsync is not supported with remoteWritesExperimental yet; use the deprecated transaction() for now
What it means
The WASM promise wrapper's transactionAsync() override throws when the database was opened with DatabaseOpts.remoteWritesExperimental. Remote-writes transactions run entirely on the remote server, so there is no local connection to hand to the callback as a Transaction handle. The library rejects the call up front instead of silently running the transaction in the wrong place. The doc comment on the override states this limitation explicitly.
Source
Thrown at bindings/javascript/sync/packages/wasm/promise-turbopack-hack.ts:333
Object.defineProperties(properties.immediate.value, properties);
Object.defineProperties(properties.exclusive.value, properties);
return properties.default.value as TransactionFunction<F>;
}
/**
* Returns a function that executes the given function in a transaction
* on a connection owned for the whole BEGIN..COMMIT window; the callback
* receives a {@link Transaction} handle as its first argument.
*
* Not supported together with {@link DatabaseOpts.remoteWritesExperimental}
* yet: remote-writes transactions run on the remote server and have no
* local connection to hand out.
*/
override transactionAsync<F extends (txn: Transaction, ...args: any[]) => Promise<any>>(
fn: F,
): AsyncTransactionFunction<F> {
if (this.#remoteWriter) {
throw new Error(
"transactionAsync is not supported with remoteWritesExperimental yet; use the deprecated transaction() for now",
);
}
return super.transactionAsync(fn);
}
/**
* close the database and relevant files
*/
async close() {
if (this.#remoteWriter) {
await this.#remoteWriter.close();
}
if (this.#engine != null) {
if (this.name != null && this.#worker != null) {
await Promise.all([
unregisterFileAtWorker(this.#worker, this.name),
unregisterFileAtWorker(this.#worker, `${this.name}-wal`),View on GitHub (pinned to bad083fafb)
Solutions
- Switch the call to the deprecated db.transaction(fn) — its override detects the remote writer and routes the whole BEGIN..COMMIT to the remote server via remoteWriter.beginTransaction/commit
- Branch on the config you constructed the database with: use transaction(fn) when remoteWritesExperimental is set, transactionAsync(fn) otherwise
- If the Transaction-handle API is a hard requirement, drop remoteWritesExperimental and use local writes plus push() to synchronize
Example fix
// before
const db = new Database("app.db", { url, authToken, remoteWritesExperimental: true });
const tx = db.transactionAsync(async (txn) => { await txn.execute("INSERT ..."); }); // throws
// after
const db = new Database("app.db", { url, authToken, remoteWritesExperimental: true });
const tx = db.transaction(async () => { await db.execute("INSERT ..."); }); // runs BEGIN..COMMIT on the remote Defensive patterns
Strategy: validation
Validate before calling
// Decide up front, from the opts you control, which transaction API is legal
const opts: DatabaseOpts = { url, authToken, remoteWritesExperimental: true };
const db = new Database(path, opts);
function makeTxn<T extends (...args: any[]) => Promise<any>>(db: Database, fn: T) {
return opts.remoteWritesExperimental
? db.transaction(fn) // remote-aware override
: db.transactionAsync(fn); // local connection handle OK
} Prevention
- Branch on your own DatabaseOpts — the wrapper's #remoteWriter is private and not queryable
- Wrap transaction creation in one helper so the remote/local split lives in a single place
- Watch release notes: transactionAsync support for remote writes is on the roadmap, so revisit once supported
When it happens
Trigger: Constructing the database with `new Database(path, { url, authToken, remoteWritesExperimental: true })` and then calling `db.transactionAsync(async (txn) => { ... })`. The throw happens synchronously inside transactionAsync() as soon as the #remoteWriter is present, before any transaction work starts.
Common situations: Enabling remoteWritesExperimental on an existing app that already used transactionAsync; upgrading @tursodatabase/sync-wasm to a version where remoteWritesExperimental was introduced; copying transactionAsync examples from the local-sync docs into a remote-writes deployment; sharing transaction helper code between local and remote-writes databases.
Related errors
- transactionAsync is not supported with remoteWritesExperimen
- transactionAsync is not supported with remoteWritesExperimen
- transactionAsync is not supported with remoteWritesExperimen
- remoteWritesExperimental requires a non-null URL
- remoteWritesExperimental requires a non-null URL
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/73d67155859dc7b2.
Report an issue: GitHub.