{"record":{"id":"412533803f4a7412","repo":"tursodatabase/turso","slug":"the-connection-is-not-open","errorCode":null,"errorMessage":"The connection is not open.","messagePattern":"The connection is not open\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs","lineNumber":641,"sourceCode":"\n        _disposed = true;\n        await base.DisposeAsync().ConfigureAwait(false);\n        failure?.Throw();\n    }\n\n    internal TursoDatabaseHandle DatabaseHandle\n    {\n        get\n        {\n            if (_managedConnection is not null)\n            {\n                if (IsReplica)\n                    return ManagedConnection.Turso;\n                throw new NotSupportedException(\n                    \"SQLite native handles are not available for direct remote connections.\");\n            }\n\n            return _database ?? throw new InvalidOperationException(\"The connection is not open.\");\n        }\n    }\n\n    internal bool HasOpenReader => _openReaderCount > 0;\n\n    internal bool IsReadOnly => _readOnly;\n\n    internal bool RecursiveTriggers => _recursiveTriggers;\n\n    internal bool ManagedReadYourWrites => _connectionOptions.ReadYourWrites;\n\n    internal void ReaderOpened() => _openReaderCount++;\n\n    internal void ReaderClosed()\n    {\n        if (_openReaderCount > 0)\n            _openReaderCount--;\n    }","sourceCodeStart":623,"sourceCodeEnd":659,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs#L623-L659","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nSqliteCommand cmd;\nusing (var conn = new SqliteConnection(cs))\n{\n    conn.Open();\n    cmd = conn.CreateCommand();\n    cmd.CommandText = \"SELECT 1\";\n} // closed\nvar r = cmd.ExecuteReader(); // DatabaseHandle throws: connection is not open\n\n// after\nusing (var conn = new SqliteConnection(cs))\n{\n    conn.Open();\n    using var cmd = conn.CreateCommand();\n    cmd.CommandText = \"SELECT 1\";\n    using var r = cmd.ExecuteReader();\n    while (r.Read()) { /* ... */ }\n}","handlingStrategy":"validation","validationCode":"static SqliteCommand NewCommandOnLiveConnection(SqliteConnection conn, string sql)\n{\n    if (conn.State != ConnectionState.Open)\n        throw new InvalidOperationException($\"Connection is {conn.State}; open it before executing commands.\");\n    return conn.CreateCommand();\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    using var cmd = conn.CreateCommand();\n    cmd.CommandText = \"SELECT 1\";\n    cmd.ExecuteScalar();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not open\"))\n{\n    // handle closed-connection use: reopen or rebuild on a fresh connection\n    throw;\n}","preventionTips":["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."],"tags":["ado-net","sqlite","turso","connection-lifecycle","internal"],"backgroundTag":"connection-not-open","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-09-06T07:15:26.990Z","contentChangedAt":"2026-09-06T07:15:26.990Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}