HangfireIO/Hangfire · error · MissingMemberException
Property '{type.FullName}.Connection' not found.
Error message
Property '{type.FullName}.Connection' not found. What it means
MissingMemberException thrown while building the expression to set the Connection property on the SqlCommandSet instance: GetProperty("Connection", Instance|Public|NonPublic) returned null for the resolved type. Hangfire reflects non-public members of the batch type; if the provider renamed or removed the Connection setter, the accessor cannot be compiled.
Source
Thrown at src/Hangfire.SqlServer/SqlCommandSet.cs:81
// GitHub Issue: https://github.com/dotnet/corefx/issues/29391
throw new NotSupportedException(".NET Core version of the System.Data.SqlClient package below 4.7.0 (which has assembly version 4.6.0.0) doesn't properly implement the SqlCommandSet class.");
}
var type = sqlClientAssembly.GetTypes().FirstOrDefault(static x => x.Name == "SqlCommandSet");
if (type == null)
{
throw new TypeLoadException($"Could not load type 'SqlCommandSet' from assembly '{sqlClientAssembly}'.");
}
return type;
});
_setConnection = SetConnection.GetOrAdd(sqlCommandSetType, static type =>
{
var p = Expression.Parameter(typeof(object));
var converted = Expression.Convert(p, type);
var connectionParameter = Expression.Parameter(typeof(DbConnection));
var connectionProperty = type.GetProperty("Connection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException($"Property '{type.FullName}.Connection' not found.");
return Expression.Lambda<Action<object, DbConnection>>(Expression.Assign(Expression.Property(converted, connectionProperty), Expression.Convert(connectionParameter, connectionProperty.PropertyType)), p, connectionParameter).Compile();
});
_setTransaction = SetTransaction.GetOrAdd(sqlCommandSetType, static type =>
{
var p = Expression.Parameter(typeof(object));
var converted = Expression.Convert(p, type);
var transactionParameter = Expression.Parameter(typeof(DbTransaction));
var transactionProperty = type.GetProperty("Transaction", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException($"Property '{type.FullName}.Transaction' not found.");
return Expression.Lambda<Action<object, DbTransaction>>(Expression.Assign(Expression.Property(converted, transactionProperty), Expression.Convert(transactionParameter, transactionProperty.PropertyType)), p, transactionParameter).Compile();
});
var batchCommandProperty = BatchCommandProperty.GetOrAdd(sqlCommandSetType, static type =>
{
return type.GetProperty("BatchCommand", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException($"Property '{type.FullName}.BatchCommand' not found.");
});
_getBatchCommand = GetBatchCommand.GetOrAdd(sqlCommandSetType, type =>
{
var p = Expression.Parameter(typeof(object));
var converted = Expression.Convert(p, type);View on GitHub (pinned to c236dd0f93)
Solutions
- Use a SqlClient package version that is known compatible with your Hangfire.SqlServer version (check release notes).
- Avoid assembly trimming/obfuscation on the SqlClient assembly.
- Upgrade Hangfire.SqlServer to a release that supports the newer internal layout.
Example fix
// before <PackageReference Include="Hangfire.SqlServer" Version="1.6.x" /> <PackageReference Include="Microsoft.Data.SqlClient" Version="5.0.0" /> // after (align versions per Hangfire.SqlServer release notes) <PackageReference Include="Hangfire.SqlServer" Version="1.8.x" /> <PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.x" />
Defensive patterns
Strategy: type-guard
Validate before calling
static bool HasConnectionProperty(Type sqlCommandSetType)
=> sqlCommandSetType.GetProperty("Connection",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null; Type guard
static bool IsSqlCommandSetUsable(Type type) =>
type.GetProperty("Connection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null; Prevention
- Avoid trimming/obfuscating the SqlClient assembly.
- Keep Hangfire.SqlServer updated alongside SqlClient.
- When evaluating a new provider, write a probe test that reflects the expected members.
When it happens
Trigger: Using a SqlClient assembly whose SqlCommandSet type exists but no longer has a Connection property discoverable via reflection (renamed property, different visibility, obfuscation).
Common situations: Provider version change that altered internal property names; an obfuscated/trimmed assembly; using Microsoft.Data.SqlClient on a version where the internal surface differs.
Related errors
- Property '{type.FullName}.BatchCommand' not found.
- Could not load type 'SqlCommandSet' from assembly '{sqlClien
- Property '{type.FullName}.Transaction' not found.
- SqlCommandSet for {connection.GetType().FullName} is not sup
- The type `{type.FullName}` does not contain a method with si
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/8ccf5797cb47f432.
Report an issue: GitHub.