HangfireIO/Hangfire · error · ArgumentNullException
action
Error message
action
What it means
Thrown by SlowLogProfiler.InvokeMeasured when the action delegate (the work to measure) is null. SlowLogProfiler measures execution time and emits a slow-log warning when a threshold is exceeded. Passing a null action is a programming contract violation — there is nothing to measure and invoke.
Source
Thrown at src/Hangfire.Core/Profiling/SlowLogProfiler.cs:45
private readonly ILog _logger;
public SlowLogProfiler(ILog logger)
: this(logger, DefaultThreshold)
{
}
public SlowLogProfiler(ILog logger, TimeSpan threshold)
{
_threshold = threshold;
_logger = logger;
}
public TResult InvokeMeasured<TInstance, TResult>(
TInstance instance,
Func<TInstance, TResult> action,
Func<TInstance, string> messageFunc = null)
{
if (action == null) throw new ArgumentNullException(nameof(action));
var startedAt = Environment.TickCount;
// TODO: Change implementation to thread-based, once it is possible to query custom services everywhere
using (new Timer(LogWarningMessage, null, _threshold, _threshold))
{
return action(instance);
}
void LogWarningMessage(object state)
{
var elapsedSec = unchecked(Environment.TickCount - startedAt) / 1_000;
var type = instance?.ToString() ?? typeof(TInstance).ToString();
var message = messageFunc?.Invoke(instance) ?? "(null)";
_logger.Warn($"Slow log: {type} is still performing \"{message}\" after {elapsedSec} sec");
}View on GitHub (pinned to c236dd0f93)
Solutions
- Pass a non-null Func<TInstance, TResult> delegate to InvokeMeasured.
- Guard the caller: if the action is null, skip the profiled call entirely instead of forwarding null.
- Verify the factory/expression producing the action returns a real delegate.
Example fix
// before profiler.InvokeMeasured(instance, action: nullFunc); // after Func<MyType, MyResult> action = inst => DoWork(inst); profiler.InvokeMeasured(instance, action);
Defensive patterns
Strategy: validation
Validate before calling
Func<TInstance, TResult> action = BuildAction();
if (action == null) throw new InvalidOperationException("No action to measure.");
profiler.InvokeMeasured(instance, action); Prevention
- Never pass a delegate that a factory may return null for — check before invoking.
- Build actions with a lambda or method group that is guaranteed non-null.
- If an operation is optional, skip the profiled call instead of forwarding null.
When it happens
Trigger: Calling slowLogProfiler.InvokeMeasured(instance, null) where the Func<TInstance, TResult> action argument is null. Occurs when a caller builds the action lazily and a factory returns null, or when a code path passes an unresolved delegate.
Common situations: Custom Hangfire extensions that wrap operations with the profiler but conditionally pass null when no operation is needed. Refactoring that drops the delegate assignment. DI or factory method returning null for the action.
Related errors
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/bbf8252329e1d94f.
Report an issue: GitHub.