DapperLib/Dapper · error · InvalidOperationException

Async operations require use of a DbConnection or an already

Error message

Async operations require use of a DbConnection or an already-open IDbConnection

What it means

TryOpenAsync throws InvalidOperationException("Async operations require use of a DbConnection or an already-open IDbConnection") when the connection passed to an async query is not a DbConnection (i.e. it is a custom/raw IDbConnection implementation). Dapper's async path calls OpenAsync, which only exists on DbConnection; a plain IDbConnection cannot be opened asynchronously. The error message is a deliberate, clearer substitute for a MissingMethodException.

Source

Thrown at Dapper/SqlMapper.Async.cs:403

            if (task.Status == TaskStatus.Faulted && Settings.DisableCommandBehaviorOptimizations(behavior, task.Exception!.InnerException!))
            { // we can retry; this time it will have different flags
                return cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken);
            }
            return task;
        }

        /// <summary>
        /// Attempts to open a connection asynchronously, with a better error message for unsupported usages.
        /// </summary>
        private static Task TryOpenAsync(this IDbConnection cnn, CancellationToken cancel)
        {
            if (cnn is DbConnection dbConn)
            {
                return dbConn.OpenAsync(cancel);
            }
            else
            {
                throw new InvalidOperationException("Async operations require use of a DbConnection or an already-open IDbConnection");
            }
        }

        /// <summary>
        /// Attempts setup a <see cref="DbCommand"/> on a <see cref="DbConnection"/>, with a better error message for unsupported usages.
        /// </summary>
        private static DbCommand TrySetupAsyncCommand(this CommandDefinition command, IDbConnection cnn, Action<IDbCommand, object?>? paramReader)
        {
            if (command.SetupCommand(cnn, paramReader) is DbCommand dbCommand)
            {
                return dbCommand;
            }
            else
            {
                throw new InvalidOperationException("Async operations require use of a DbConnection or an IDbConnection where .CreateCommand() returns a DbCommand");
            }
        }

View on GitHub (pinned to 72a54c475f)

Solutions

  1. Use a connection type derived from System.Data.Common.DbConnection (the standard provider types like SqlConnection, NpgsqlConnection, MySqlConnection, SQLiteConnection all are).
  2. Open the connection yourself before the async call — but the message notes DbConnection is still required, so prefer switching to a real DbConnection-derived type.
  3. For tests, mock at the DbConnection level or use a provider that implements it (e.g. Microsoft.Data.Sqlite).

Example fix

// before (custom raw IDbConnection)
public class MyConn : IDbConnection { ... }
await cnn.QueryAsync<T>(sql); // throws

// after
cnn.Open(); // pre-open; and/or switch to a DbConnection-derived type
await cnn.QueryAsync<T>(sql);
Defensive patterns

Strategy: type-guard

Validate before calling

if (cnn is not DbConnection) throw new InvalidOperationException("Async Dapper requires a DbConnection-derived connection.");
await cnn.QueryAsync<T>(sql);

Type guard

static bool SupportsAsync(IDbConnection c) => c is System.Data.Common.DbConnection;

Try / catch

try { await cnn.QueryAsync<T>(sql); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DbConnection"))
{ /* switch to a DbConnection-derived provider type */ }

Prevention

When it happens

Trigger: Passing a custom IDbConnection implementation that does not derive from System.Data.Common.DbConnection to any async Dapper method (QueryAsync, ExecuteAsync, etc.) while the connection is closed — Dapper then tries to open it asynchronously and fails.

Common situations: Mocking IDbConnection for tests and exercising async APIs; wrapping a legacy provider whose connection type predates DbConnection; a third-party ADO.NET shim that only implements IDbConnection.

Related errors


AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13). Data as JSON: /api/errors/4b34a8d9c76db287. Report an issue: GitHub.