{"record":{"id":"6d3f099dd3b9d137","repo":"tursodatabase/turso","slug":"executebatch-requires-an-open-connection","errorCode":null,"errorMessage":"ExecuteBatch requires an open connection.","messagePattern":"ExecuteBatch requires an open connection\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteBatch.cs","lineNumber":373,"sourceCode":"        catch\n        {\n            managedBatch.Dispose();\n            throw;\n        }\n    }\n\n    private SqliteConnection ValidateBatch()\n    {\n        var connection = _connection\n                         ?? throw new InvalidOperationException(\n                             \"Connection must be set before executing a batch.\");\n        if (!connection.IsManagedConnection)\n        {\n            throw new NotSupportedException(\n                \"SQLite facade batches are available only for direct remote or embedded replica connections.\");\n        }\n        if (connection.State != ConnectionState.Open)\n            throw new InvalidOperationException(Properties.Resources.CallRequiresOpenConnection(\"ExecuteBatch\"));\n        if (_transaction is { IsCompleted: true })\n            throw new InvalidOperationException(Properties.Resources.TransactionCompleted);\n        if (_transaction is not null && !ReferenceEquals(_transaction.Connection, connection))\n            throw new InvalidOperationException(Properties.Resources.TransactionConnectionMismatch);\n        if (connection.Transaction is not null\n            && !ReferenceEquals(_transaction, connection.Transaction))\n        {\n            throw new InvalidOperationException(Properties.Resources.TransactionRequired);\n        }\n        if (_batchCommands.Count == 0)\n            throw new InvalidOperationException(\"Batch must contain at least one command.\");\n\n        return connection;\n    }\n\n    private int SetRecordsAffected(BatchState state)\n    {\n        var total = 0;","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data.Sqlite/SqliteBatch.cs#L355-L391","documentation":"ValidateBatch enforces that the batch's connection is open before executing; a closed or broken connection throws InvalidOperationException with the 'ExecuteBatch requires an open connection' message (via CallRequiresOpenConnection resource), mirroring standard ADO.NET behavior.","triggerScenarios":"Calling ExecuteReader/ExecuteBatch before calling connection.Open(), after connection.Close()/Dispose(), or after the connection dropped (broken state).","commonSituations":"Async code that opens the connection in another method but awaits it incorrectly; connection disposed by a using block before the batch runs; network drop putting a remote connection into a non-Open state.","solutions":["Call await connection.OpenAsync() (or Open()) before executing the batch","Check connection.State == ConnectionState.Open before executing and open if needed","Don't dispose the connection (using scope) before the batch completes; for drops, recreate/reopen the connection"],"exampleFix":"// before\nvar conn = new SqliteConnection(cs);\nawait batch.ExecuteReaderAsync(); // InvalidOperationException\n// after\nvar conn = new SqliteConnection(cs);\nawait conn.OpenAsync();\nawait batch.ExecuteReaderAsync();","handlingStrategy":"validation","validationCode":"if (connection.State != ConnectionState.Open)\n    await connection.OpenAsync();","typeGuard":"static bool IsOpen(System.Data.ConnectionState s) => s == ConnectionState.Open;","tryCatchPattern":"try { await batch.ExecuteReaderAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"open connection\") || ex.Message.Contains(\"open\")) { /* reopen connection and retry once */ }","preventionTips":["Always open the connection immediately before batch execution","Avoid disposing the connection inside a using block that ends before the batch runs","Check ConnectionState.Open in retry/reconnect logic for remote connections"],"tags":["dotnet","batch","connection","connection-state"],"backgroundTag":"connection-refused","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"}