tursodatabase/turso · error · ArgumentException
Transaction must be a TursoTransaction.
Error message
Transaction must be a TursoTransaction.
What it means
The DbTransaction setter on TursoCommand only accepts TursoTransaction (TursoCommand.cs:86-98) — the transaction object begun on the same TursoConnection. A transaction from another provider, or from a different connection, cannot be attached and throws ArgumentException; assigning null detaches cleanly.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoCommand.cs:96
protected override DbParameterCollection DbParameterCollection => _parameterCollection;
public new virtual TursoParameterCollection Parameters => _parameterCollection;
protected override DbTransaction? DbTransaction
{
get => _transaction;
set
{
if (value is null)
{
_transaction = null;
return;
}
_transaction = value as TursoTransaction
?? throw new ArgumentException("Transaction must be a TursoTransaction.", nameof(value));
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_statement?.Dispose();
}
public override void Cancel()
{
}
public override int ExecuteNonQuery()
{
if (_connection?.IsRemote == true)
return ExecuteRemoteNonQueryAsync(CancellationToken.None).GetAwaiter().GetResult();
View on GitHub (pinned to c1e5928725)
Solutions
- Begin the transaction on the TursoConnection and assign that: cmd.Transaction = await tursoConn.BeginTransactionAsync(ct);
- When rebinding a command to a different connection, first set cmd.Transaction = null, then assign the new TursoConnection and its transaction.
- Keep connection, command, and transaction objects sourced from one provider and one connection instance.
Example fix
// before cmd.Connection = tursoConn; cmd.Transaction = oldSqlTransaction; // throws ArgumentException // after using var tx = tursoConn.BeginTransaction(); cmd.Connection = tursoConn; cmd.Transaction = tx;
Defensive patterns
Strategy: type-guard
Validate before calling
if (tx is not null && tx is not TursoTransaction)
throw new InvalidOperationException("Transaction belongs to a different provider/connection."); Type guard
static bool IsTursoTransaction(DbTransaction? t) => t is null || t is TursoTransaction;
Try / catch
try
{
cmd.Transaction = tx;
}
catch (ArgumentException ex) when (ex.ParamName == "value")
{
// tx is foreign; begin a fresh transaction on the TursoConnection instead.
} Prevention
- Begin transactions on the same TursoConnection whose commands will use them.
- Clear cmd.Transaction before rebinding a command to a new connection.
- Keep one provider per unit of work; never share DbTransaction across providers.
When it happens
Trigger: cmd.Transaction = sqlTransaction; where sqlTransaction came from SqlConnection.BeginTransaction(); or reassigning a command to a new connection while it still holds a transaction from the old one.
Common situations: Refactors that swap the connection in a helper but keep the old transaction; cross-provider code that shares System.Data.Common objects; partial migration where one branch of code still uses SqlClient transactions.
Related errors
- Batch command must be a TursoBatchCommand.
- Connection must be a TursoConnection.
- Parameter must be of type TursoParameter
- Transaction must be a SqliteTransaction.
- Turso database is closed.
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20).
Data as JSON: /api/errors/5b714a1ba8421c39.
Report an issue: GitHub.