tursodatabase/turso · error · InvalidOperationException
Turso database is closed.
Error message
Turso database is closed.
What it means
BeginDbTransaction throws InvalidOperationException when the connection has neither a local database handle nor a remote client (TursoConnection.cs:117-122) — it was never opened, or was closed/disposed. Transactions attach to an active database session, so there is nothing to begin one on.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoConnection.cs:163
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
Close();
}
finally
{
_disposed = true;
base.Dispose(disposing);
}
}
protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
if (_turso is null && _remoteClient is null)
{
throw new InvalidOperationException("Turso database is closed.");
}
return new TursoTransaction(this, isolationLevel);
}
protected override DbCommand CreateDbCommand()
{
return new TursoCommand(this);
}
protected override DbBatch CreateDbBatch()
{
if (!CanCreateBatch)
throw new NotSupportedException("Turso batch execution requires a direct remote or embedded replica connection.");
return new TursoBatch(this);
}
View on GitHub (pinned to 6c72522679)
Solutions
- Call conn.Open() (or await conn.OpenAsync(ct)) before BeginTransaction.
- Guard shared code: if (conn.State != ConnectionState.Open) throw a clear error or open first.
- Audit connection lifetimes in DI so disposed connections are not handed to new work.
Example fix
// before using var conn = new TursoConnection(cs); using var tx = conn.BeginTransaction(); // never opened -> throws // after using var conn = new TursoConnection(cs); conn.Open(); using var tx = conn.BeginTransaction();
Defensive patterns
Strategy: validation
Validate before calling
if (conn.State != ConnectionState.Open)
throw new InvalidOperationException("Open the TursoConnection before beginning a transaction.");
// or: await conn.OpenAsync(ct); Prevention
- Treat Open as a mandatory step; Turso never auto-opens.
- Keep BeginTransaction inside the same scope that owns the open connection.
- Check State in generic transaction wrappers before delegating.
When it happens
Trigger: var conn = new TursoConnection(cs); conn.BeginTransaction(); without calling Open; or BeginTransaction after Close/Dispose (e.g. outside a using scope that already ended).
Common situations: A refactor removed the conn.Open() call; assuming SqlClient-style implicit open via pooling (Turso requires explicit Open); connection held past its using block or disposed by DI and then reused.
Related errors
- The connection is already open.
- Connection must be a TursoConnection.
- Transaction must be a TursoTransaction.
- Connection must be set before executing a command.
- Connection must be set before preparing a command.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/6ceb631bf0573ca1.
Report an issue: GitHub.