HangfireIO/Hangfire · error · NotSupportedException
Parameters, passed by reference, are not supported: there is
Error message
Parameters, passed by reference, are not supported: there is no guarantee that specified method will be invoked inside the same process.
What it means
NotSupportedException thrown by Job.Validate when a parameter's ParameterType.IsByRef is true — i.e., the method declares a 'ref' parameter. Like out parameters, ref parameters require bidirectional in-place mutation at the call site, which is impossible when the method runs in a different process and arguments are serialized copies. Hangfire rejects this at definition time to prevent silent data loss.
Source
Thrown at src/Hangfire.Core/Common/Job.cs:526
"Argument count must be equal to method parameter count.",
argumentParameterName);
}
foreach (var parameter in parameters)
{
// There is no guarantee that specified method will be invoked
// in the same process. Therefore, output parameters and parameters
// passed by reference are not supported.
if (parameter.IsOut)
{
throw new NotSupportedException(
"Output parameters are not supported: there is no guarantee that specified method will be invoked inside the same process.");
}
if (parameter.ParameterType.IsByRef)
{
throw new NotSupportedException(
"Parameters, passed by reference, are not supported: there is no guarantee that specified method will be invoked inside the same process.");
}
var parameterTypeInfo = parameter.ParameterType.GetTypeInfo();
if (parameterTypeInfo.IsSubclassOf(typeof(Delegate)) || parameterTypeInfo.IsSubclassOf(typeof(Expression)))
{
throw new NotSupportedException(
"Anonymous functions, delegates and lambda expressions aren't supported in job method parameters: it's very hard to serialize them and all their scope in general.");
}
}
}
private static object[] GetExpressionValues(ReadOnlyCollection<Expression> expressions)
{
var result = expressions.Count > 0 ? new object[expressions.Count] : [];
var index = 0;
View on GitHub (pinned to c236dd0f93)
Solutions
- Remove the ref modifier; pass the value by value and return the updated value via the method's return type.
- Wrap the ref-based method in a public method with plain parameters and enqueue the wrapper.
- If mutation semantics are required, persist the value in storage keyed by job ID and read/write it inside the job body.
Example fix
// before — ref parameter, unsupported
public class Worker {
public void Run(ref int counter) { counter++; }
}
// after — return the new value
public class Worker {
public int Run(int counter) { return counter + 1; }
}
BackgroundJob.Enqueue<Worker>(x => x.Run(0)); Defensive patterns
Strategy: validation
Validate before calling
if (method.GetParameters().Any(p => p.ParameterType.IsByRef))
throw new NotSupportedException("Job method has ref parameters; remove them before creating the job."); Type guard
public static bool HasNoRefParameters(MethodInfo m)
=> m != null && m.GetParameters().All(p => !p.ParameterType.IsByRef); Try / catch
try { BackgroundJob.Enqueue<T>(x => x.Work()); }
catch (NotSupportedException ex) when (ex.Message.Contains("passed by reference")) { /* remove the ref param, return the new value instead */ } Prevention
- Never declare ref parameters on job methods; return updated values via the return type.
- Wrap ref-parameter library calls in a public method with plain parameters.
- Persist mutable shared state in storage keyed by job ID rather than relying on ref.
When it happens
Trigger: Enqueuing () => service.Run(ref counter); a method declared as public void Run(ref int x); using methods that swap or mutate caller-provided values via ref.
Common situations: Wrapping methods designed for in-process computation (e.g., exchange-and-compare patterns) as jobs; refactoring to add a ref parameter; interop with APIs that use ref for performance.
Related errors
- Output parameters are not supported: there is no guarantee t
- Only public methods can be invoked in the background. Ensure
- Job method can not contain unassigned generic type parameter
- Global methods are not supported. Use class methods instead.
- Async void methods are not supported. Use async Task instead
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/5d0ad44f1f221965.
Report an issue: GitHub.