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

transactionAsync() hands the callback a Transaction handle bound to a connection owned for the whole BEGIN..COMMIT window. Under remoteWritesExperimental, transactions run on the remote server via RemoteWriter and there is no local connection to hand out, so the override deliberately throws when a remote writer is installed. The error tells you to use the (deprecated) transaction() wrapper, whose callback runs against the database while BEGIN/COMMIT are sent to the remote.

Source

Thrown at bindings/javascript/sync/packages/native/promise.ts:318

        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
     */
    override async close(): Promise<void> {
        if (this.#remoteWriter) {
            await this.#remoteWriter.close();
        }
        await super.close();
        if (this.#engine != null) {
            this.#engine.close();
        }
    }

View on GitHub (pinned to bad083fafb)

Solutions

  1. Switch that call site to db.transaction(fn), which is supported with remoteWritesExperimental.
  2. Branch on your remote-writes flag: use transaction() when enabled, transactionAsync() otherwise.
  3. Track upstream support — the doc comment marks the combination as unsupported 'yet', so re-test after upgrades.

Example fix

// before
const runTxn = db.transactionAsync(fn); // db opened with remoteWritesExperimental: true

// after
const runTxn = remoteWritesEnabled
  ? db.transaction(fn)      // remote-writes transactions run on the server
  : db.transactionAsync(fn);
Defensive patterns

Strategy: validation

Validate before calling

// choose the transaction API based on how the DB was opened
const useTxnAsync = !remoteWritesEnabled;
const runTxn = useTxnAsync ? db.transactionAsync(fn) : db.transaction(fn);

Try / catch

try {
  return await db.transactionAsync(fn)(...args);
} catch (e) {
  if (e instanceof Error && /transactionAsync is not supported/.test(e.message)) {
    return await db.transaction(fn)(...args); // remote-writes path
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling db.transactionAsync(fn) on a Database constructed with remoteWritesExperimental: true and a URL; generic ORM/data-layer code that standardizes on transactionAsync across sync and non-sync deployments.

Common situations: Enabling the experimental remote-writes feature in an app already built on transactionAsync; shared middleware that always uses the async-transaction API; upgrading the sync package and hitting the new guard.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/59d9621557e98b30. Report an issue: GitHub.