tursodatabase/turso · error · InvalidOperationException

No remote transaction is active on this connection.

Error message

No remote transaction is active on this connection.

What it means

CommitRemoteTransaction refuses to send COMMIT when _remoteTransactionActive is false: 'No remote transaction is active on this connection.' The flag is cleared by successful Commit/Rollback, by Close, and by session invalidation, so this error means the connection-level transaction already ended (or never began) while commit was still requested.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoConnection.cs:262

                .GetResult();
        }
        catch (TursoRemoteSqlException)
        {
            _remoteTransactionActive = false;
            throw;
        }
        catch
        {
            InvalidateRemoteSession();
            throw;
        }
    }

    internal void CommitRemoteTransaction()
    {
        var remoteClient = _remoteClient ?? throw new InvalidOperationException("Turso database is closed.");
        if (!_remoteTransactionActive)
            throw new InvalidOperationException("No remote transaction is active on this connection.");

        try
        {
            remoteClient
                .ExecuteAsync("COMMIT", new TursoParameterCollection(), wantRows: false, DefaultTimeout, closeAfter: false, CancellationToken.None)
                .GetAwaiter()
                .GetResult();
        }
        catch (TursoRemoteSqlException)
        {
            throw;
        }
        catch
        {
            InvalidateRemoteSession();
            throw;
        }

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Commit exactly once per transaction; after Commit or Rollback (or an error path that invalidated the session) treat the transaction as finished
  2. In finally blocks, commit only if your own flag says the work succeeded and the transaction has not completed
  3. Do not interleave raw BEGIN/COMMIT SQL with TursoTransaction on the same remote connection
  4. Catch InvalidOperationException at the boundary and re-verify database state before assuming the commit landed

Example fix

// before
var committed = false;
try { /* work */ committed = true; }
finally { tx.Commit(); } // throws if tx already ended or never began

// after
var committed = false;
try { /* work */ committed = true; }
finally { if (committed && !tx.IsCompleted) tx.Commit(); }
Defensive patterns

Strategy: validation

Validate before calling

var ok = false;
try { /* work */ tx.Commit(); ok = true; }
finally { if (!ok && !tx.IsCompleted) tx.Rollback(); }

Type guard

static bool IsUsableTransaction(TursoTransaction tx) => !tx.IsCompleted;

Try / catch

try { tx.Commit(); }
catch (InvalidOperationException ex) when (ex.Message == "No remote transaction is active on this connection.")
{
    // transaction already ended; verify database state if the outcome matters
}

Prevention

When it happens

Trigger: Calling commit paths twice at the connection level; committing after the transaction was already rolled back or invalidated by an error; transaction bookkeeping desync after mixing manual BEGIN/COMMIT SQL statements with TursoTransaction on a remote connection; committing after Dispose-on-closed-connection completed the transaction out-of-band.

Common situations: Retry loops that re-commit the same unit of work; finally blocks that commit 'for safety' after an explicit rollback; wrappers that hold a TursoTransaction past its real end and commit again in a callback.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/eeec901e151d3db2. Report an issue: GitHub.