HangfireIO/Hangfire · error · NotSupportedException
SqlCommandSet for {connection.GetType().FullName} is not sup
Error message
SqlCommandSet for {connection.GetType().FullName} is not supported, use regular commands instead What it means
NotSupportedException thrown by the SqlCommandSet constructor's catch-all: any reflection/setup exception (TypeLoadException, MissingMemberException, etc.) while probing the provider's batch type is wrapped here with the connection's full type name, directing you to fall back to regular (non-batched) commands. It is the umbrella error for 'this provider can't be used for batched inserts'.
Source
Thrown at src/Hangfire.SqlServer/SqlCommandSet.cs:129
var p = Expression.Parameter(typeof(object));
var converted = Expression.Convert(p, type);
return Expression.Lambda<Func<object, int>>(Expression.Call(converted, "ExecuteNonQuery", null), p).Compile();
});
_disposeMethod = DisposeMethod.GetOrAdd(sqlCommandSetType, static type =>
{
var p = Expression.Parameter(typeof(object));
var converted = Expression.Convert(p, type);
return Expression.Lambda<Action<object>>(Expression.Call(converted, "Dispose", null), p).Compile();
});
_constructor = SqlCommandSetConstructor.GetOrAdd(sqlCommandSetType, static type =>
{
var ctor = Expression.New(type);
return Expression.Lambda<Func<object>>(ctor).Compile();
});
}
catch (Exception exception) when (exception.IsCatchableExceptionType())
{
throw new NotSupportedException($"SqlCommandSet for {connection.GetType().FullName} is not supported, use regular commands instead", exception);
}
_instance = _constructor();
}
public DbConnection Connection
{
set => _setConnection(_instance, value);
}
public DbTransaction Transaction
{
set => _setTransaction(_instance, value);
}
public DbCommand BatchCommand => _getBatchCommand(_instance);
public int CommandCount { get; private set; }
View on GitHub (pinned to c236dd0f93)
Solutions
- Read the InnerException to find the exact reflection failure (type missing, property missing, etc.) and address that specifically.
- Switch to a supported Microsoft.Data.SqlClient / System.Data.SqlClient version and disable trimming.
- If the provider is genuinely unsupported, configure Hangfire to use regular (non-batch) command execution if such an option is available, or replace the test fake with a real provider connection.
Example fix
// before (fake connection in integration test) var conn = new FakeDbConnection(); using var batch = new SqlCommandSet(conn); // -> NotSupportedException // after var conn = new SqlConnection(realConnectionString); conn.Open(); using var batch = new SqlCommandSet(conn);
Defensive patterns
Strategy: try-catch
Validate before calling
static bool ProviderSupportsBatch(DbConnection conn)
{
try
{
var t = conn.GetType().Assembly.GetTypes().FirstOrDefault(x => x.Name == "SqlCommandSet");
if (t == null) return false;
foreach (var p in new[] { "Connection", "Transaction", "BatchCommand" })
if (t.GetProperty(p, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)
return false;
return true;
}
catch { return false; }
} Try / catch
try
{
using var batch = new SqlCommandSet(connection);
}
catch (NotSupportedException ex)
{
logger.Warn(ex.InnerException, "Falling back to regular commands for {Conn}", connection.GetType().FullName);
// execute commands individually
} Prevention
- Always inspect InnerException — it holds the precise reflection failure.
- Don't pass mocked/fake DbConnection through the batch path.
- Pin compatible provider + Hangfire.SqlServer versions and disable trimming.
When it happens
Trigger: Constructing SqlCommandSet for a DbConnection whose provider fails any of the reflection steps (type load, property binding, delegate compilation); common with an unsupported/trimmed/incompatible provider.
Common situations: Incompatible SqlClient version, trimmed publish, a mocked/fake DbConnection in tests, or a third-party provider that does not mirror SqlClient's internal SqlCommandSet.
Related errors
- Could not load type 'SqlCommandSet' from assembly '{sqlClien
- Property '{type.FullName}.Connection' not found.
- Property '{type.FullName}.Transaction' not found.
- Property '{type.FullName}.BatchCommand' not found.
- Only public methods can be invoked in the background. Ensure
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/9c8ad98b670c7a83.
Report an issue: GitHub.