tursodatabase/turso · error · ArgumentException

Transaction must be a SqliteTransaction.

Error message

Transaction must be a SqliteTransaction.

What it means

SqliteBatch.Transaction accepts only a Turso SqliteTransaction; the setter downcasts and throws ArgumentException when a non-null DbTransaction of another type is assigned. Unlike Connection, a null assignment is accepted and clears the transaction.

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteBatch.cs:55

        {
            _connection = value as SqliteConnection
                          ?? (value is null
                              ? null
                              : throw new ArgumentException(
                                  "Connection must be a SqliteConnection.",
                                  nameof(value)));
            if (_connection is not null)
                _timeout = _connection.DefaultTimeout;
        }
    }

    protected override DbTransaction? DbTransaction
    {
        get => _transaction;
        set => _transaction = value as SqliteTransaction
                             ?? (value is null
                                 ? null
                                 : throw new ArgumentException(
                                     "Transaction must be a SqliteTransaction.",
                                     nameof(value)));
    }

    public override int Timeout
    {
        get => _timeout;
        set
        {
            ArgumentOutOfRangeException.ThrowIfNegative(value);
            _timeout = value;
        }
    }

    public override void Cancel()
    {
        _activeBatch?.Cancel();
    }

View on GitHub (pinned to 6c72522679)

Solutions

  1. Begin the transaction on the same Turso connection: batch.Transaction = (SqliteTransaction)connection.BeginTransaction(), or use connection.BeginTransaction() typed as SqliteTransaction
  2. Ensure the variable holding the transaction is typed Turso.Data.Sqlite.SqliteTransaction, not DbTransaction
  3. Remove duplicate/conflicting provider packages so only one SqliteTransaction type is in scope

Example fix

// before
DbTransaction tx = otherConnection.BeginTransaction();
batch.Transaction = tx; // ArgumentException
// after
var tx = connection.BeginTransaction(); // Turso SqliteTransaction
batch.Transaction = tx;
Defensive patterns

Strategy: type-guard

Validate before calling

if (tx is not Turso.Data.Sqlite.SqliteTransaction)
    throw new ArgumentException($"Expected Turso SqliteTransaction, got {tx?.GetType().FullName}");

Type guard

static bool IsTursoSqliteTransaction(DbTransaction? t) => t is Turso.Data.Sqlite.SqliteTransaction;

Try / catch

try { batch.Transaction = tx; }
catch (ArgumentException ex) when (ex.ParamName == "value") { /* recreate tx from the same Turso connection */ }

Prevention

When it happens

Trigger: Assigning a transaction obtained from a different provider (e.g. Microsoft.Data.Sqlite SqliteTransaction, NpgsqlTransaction) or from DbConnection.BeginTransaction() on a non-Turso connection to SqliteBatch.DbTransaction/Transaction.

Common situations: Mixing ADO.NET provider packages; storing the transaction in a base-type (DbTransaction) variable or repository abstraction and passing it back to the batch; refactor from Microsoft.Data.Sqlite to Turso without updating transaction creation.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/8166b845aebd6a9b. Report an issue: GitHub.