dotnet/reactive · error · ArgumentNullException
scheduler (Value cannot be null)
Error message
scheduler (Value cannot be null)
What it means
System.Reactive's ScheduleAsync extension requires a non-null IScheduler receiver. Passing null causes an ArgumentNullException with message "Value cannot be null (Parameter 'scheduler')". The library validates up front so no scheduling machinery is initialized for an invalid call.
Solutions
- Use a concrete scheduler instance such as Scheduler.Default, TaskPoolScheduler.Default, or NewThreadScheduler.Default.
- Null-check the scheduler before calling and substitute Scheduler.Default when absent.
- Correct the DI registration or factory that yields the null scheduler.
Example fix
// before IScheduler scheduler = null; scheduler.ScheduleAsync(state, dueTime, action); // throws // after var scheduler = Scheduler.Default; scheduler.ScheduleAsync(state, dueTime, action);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler == null) scheduler = Scheduler.Default;
Type guard
bool HasScheduler(IScheduler s) => s is not null;
Try / catch
try { disposable = scheduler.ScheduleAsync(state, dueTime, action); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { disposable = Scheduler.Default.ScheduleAsync(state, dueTime, action); } Prevention
- Prefer `var sched = injectedScheduler ?? Scheduler.Default;` before scheduling.
- Register IScheduler in the DI container to guarantee a non-null injection.
- Do not rely on the compiler to catch null extension-method receivers.
When it happens
Trigger: Calling scheduler.ScheduleAsync<TState>(state, dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action) on a null IScheduler receiver — legal syntax because it is a C# extension method.
Common situations: DI-resolved scheduler was not registered and injected as null; a custom scheduler factory returned null; scheduler variable captured before initialization.
Related errors
- action (Value cannot be null)
- scheduler (Value cannot be null)
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'scheduler')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/d4d0d6a1698e8d35.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Async.cs:381
return ScheduleAsync_(scheduler, state, dueTime, action);
}
/// <summary>
/// Schedules work using an asynchronous method, allowing for cooperative scheduling in an imperative coding style.
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="scheduler">Scheduler to schedule work on.</param>
/// <param name="state">State to pass to the asynchronous method.</param>
/// <param name="dueTime">Absolute time at which to execute the action.</param>
/// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
/// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
{
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
return ScheduleAsync_(scheduler, state, dueTime, action);
}
/// <summary>
/// Schedules work using an asynchronous method, allowing for cooperative scheduling in an imperative coding style.
/// </summary>
/// <param name="scheduler">Scheduler to schedule work on.</param>
/// <param name="dueTime">Absolute time at which to execute the action.</param>
/// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
/// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>View on GitHub (pinned to 94b5d5ab91)