{"record":{"id":"59f7088bdf7a2a26","repo":"tursodatabase/turso","slug":"method-requires-an-open-connection","errorCode":null,"errorMessage":"{method} requires an open connection.","messagePattern":"(.+?) requires an open connection\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs","lineNumber":344,"sourceCode":"\n    public static void ClearPool(SqliteConnection connection)\n    {\n        ArgumentNullException.ThrowIfNull(connection);\n    }\n\n    public new virtual SqliteTransaction BeginTransaction()\n        => BeginTransaction(IsolationLevel.Unspecified);\n\n    public virtual SqliteTransaction BeginTransaction(bool deferred)\n        => BeginTransaction(IsolationLevel.Unspecified, deferred);\n\n    public new virtual SqliteTransaction BeginTransaction(IsolationLevel isolationLevel)\n        => BeginTransaction(isolationLevel, deferred: isolationLevel == IsolationLevel.ReadUncommitted);\n\n    public virtual SqliteTransaction BeginTransaction(IsolationLevel isolationLevel, bool deferred)\n    {\n        if (State != ConnectionState.Open)\n            throw new InvalidOperationException(Properties.Resources.CallRequiresOpenConnection(nameof(BeginTransaction)));\n        if (Transaction is not null)\n            throw new InvalidOperationException(Properties.Resources.ParallelTransactionsNotSupported);\n\n        Transaction = new SqliteTransaction(this, isolationLevel, deferred);\n        return Transaction;\n    }\n\n    public virtual void CreateCollation(string name, Comparison<string>? comparison)\n    {\n        RegisterCollation(name, comparison is null ? null : (left, right) => comparison(left, right));\n    }\n\n    public virtual void CreateCollation<T>(string name, T state, Func<T, string, string, int>? comparison)\n    {\n        RegisterCollation(name, comparison is null ? null : (left, right) => comparison(state, left, right));\n    }\n\n    public virtual void CreateFunction<TResult>(string name, Func<TResult>? function, bool isDeterministic = false)","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs#L326-L362","documentation":"BeginTransaction checks State before doing anything and throws InvalidOperationException when the connection is not Open. Unlike some providers that open implicitly, this one requires an explicit Open() first; transactions cannot start against a closed connection because they need a live native database handle. The same CallRequiresOpenConnection guard covers other APIs (BackupDatabase, and the internal DatabaseHandle/EnsureOpen used by command execution).","triggerScenarios":"'var conn = new SqliteConnection(cs); var tx = conn.BeginTransaction();' with no Open() in between; BeginTransaction in a unit test whose fixture opens the connection asynchronously and races; helpers that assume lazy connection opening; calling BeginTransaction after Close() on a reused connection object.","commonSituations":"Ported from providers with implicit open (EF Core patterns usually open for you, raw ADO.NET does not), connection lifecycle split across methods where Open happens later than expected, and mock-heavy tests that never exercise the real open path.","solutions":["Call conn.Open() before conn.BeginTransaction().","Centralize the check in an EnsureOpen helper: 'if (conn.State != ConnectionState.Open) conn.Open();'.","Verify in debuggers/logs that the same connection instance you transact on is the one that was opened (not a copy or a different field)."],"exampleFix":"// before\nusing var conn = new SqliteConnection(cs);\nusing var tx = conn.BeginTransaction(); // throws: requires an open connection\n\n// after\nusing var conn = new SqliteConnection(cs);\nconn.Open();\nusing var tx = conn.BeginTransaction();","handlingStrategy":"validation","validationCode":"static SqliteTransaction BeginTransactionSafe(SqliteConnection conn)\n{\n    if (conn.State != ConnectionState.Open)\n        conn.Open();\n    return conn.BeginTransaction();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Establish the invariant 'open once, at the composition root' for each connection.","Check State in test fixtures before starting transactions.","Static analysis: flag BeginTransaction calls on connections not obviously preceded by Open."],"tags":["ado-net","sqlite","turso","transactions","connection-lifecycle"],"backgroundTag":"connection-not-open","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}