tursodatabase/turso · error · InvalidOperationException
The connection is not open.
Error message
The connection is not open.
What it means
The internal DatabaseHandle property throws InvalidOperationException('The connection is not open.') whenever _database is null, yet some internal API reached for the native handle. It is the provider's central 'handle exists' gate, used by command preparation, options application, and other internals. Seeing it as a user means you invoked a member (directly or via a SqliteCommand/reader operation) that needs the native database after the connection was closed or before it was opened.
Source
Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs:641
_disposed = true;
await base.DisposeAsync().ConfigureAwait(false);
failure?.Throw();
}
internal TursoDatabaseHandle DatabaseHandle
{
get
{
if (_managedConnection is not null)
{
if (IsReplica)
return ManagedConnection.Turso;
throw new NotSupportedException(
"SQLite native handles are not available for direct remote connections.");
}
return _database ?? throw new InvalidOperationException("The connection is not open.");
}
}
internal bool HasOpenReader => _openReaderCount > 0;
internal bool IsReadOnly => _readOnly;
internal bool RecursiveTriggers => _recursiveTriggers;
internal bool ManagedReadYourWrites => _connectionOptions.ReadYourWrites;
internal void ReaderOpened() => _openReaderCount++;
internal void ReaderClosed()
{
if (_openReaderCount > 0)
_openReaderCount--;
}View on GitHub (pinned to 6c72522679)
Solutions
- Re-open the connection (or use a fresh one) before executing further commands.
- Scope every command/reader strictly inside the connection's open lifetime ('using var conn' outermost).
- For retries, rebuild the command from a live connection instead of replaying a command bound to a dead one.
Example fix
// before
SqliteCommand cmd;
using (var conn = new SqliteConnection(cs))
{
conn.Open();
cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1";
} // closed
var r = cmd.ExecuteReader(); // DatabaseHandle throws: connection is not open
// after
using (var conn = new SqliteConnection(cs))
{
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1";
using var r = cmd.ExecuteReader();
while (r.Read()) { /* ... */ }
} Defensive patterns
Strategy: validation
Validate before calling
static SqliteCommand NewCommandOnLiveConnection(SqliteConnection conn, string sql)
{
if (conn.State != ConnectionState.Open)
throw new InvalidOperationException($"Connection is {conn.State}; open it before executing commands.");
return conn.CreateCommand();
} Try / catch
try
{
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1";
cmd.ExecuteScalar();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not open"))
{
// handle closed-connection use: reopen or rebuild on a fresh connection
throw;
} Prevention
- Structure disposal as nested usings: connection outermost, then command, then reader.
- Never cache commands across close/open cycles; recreate them from the live connection.
- In async flows, ensure continuations that use the connection cannot outlive its scope.
When it happens
Trigger: Executing a command after conn.Close()/Dispose() (e.g. a cached SqliteCommand reused across a close/open cycle); calling EnableExtensions/LoadExtension internals or schema routines on a never-opened connection; async continuations that resume after the connection was disposed; objects that captured the connection when it was open and outlive it.
Common situations: Pooled/cached commands or readers outliving their connection, fire-and-forget tasks racing disposal, retry logic that re-executes against a closed connection, and ordering bugs where Close runs before the last reader.
Related errors
- {method} requires an open connection.
- The connection string can only be set when the connection is
- The connection is already open.
- Changing databases is not supported.
- Encryption is not supported by {libraryName}.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/412533803f4a7412.
Report an issue: GitHub.