dotnet/reactive · error · ArgumentNullException
scheduler
Error message
scheduler
What it means
The 15-argument ToAsync overload with a scheduler throws ArgumentNullException with parameter name 'scheduler' when the IScheduler argument is null. The action check has already passed at this point; Rx requires a concrete scheduler to dispatch the asynchronous action invocation.
Solutions
- Pass Scheduler.Default, Scheduler.TaskPool, Scheduler.ThreadPool, or a custom IScheduler.
- Fix the null source of the scheduler (DI registration, config, factory).
- Use the single-argument ToAsync overload if default scheduling suffices.
- Coalesce: scheduler ?? Scheduler.Default.
Example fix
// before Observable.ToAsync(action, configuredScheduler); // configuredScheduler is null // after Observable.ToAsync(action, configuredScheduler ?? Scheduler.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); // or scheduler ??= Scheduler.Default;
Type guard
bool HasScheduler(IScheduler s) => s != null;
Try / catch
try { Observable.ToAsync(action, scheduler); } catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* substitute Scheduler.Default */ } Prevention
- Coalesce nullable schedulers: scheduler ?? Scheduler.Default
- Register a default IScheduler in your DI container
- In tests, always wire a TestScheduler before exercising ToAsync
When it happens
Trigger: Calling Observable.ToAsync(action, (IScheduler)null) with a valid action but a null scheduler reference.
Common situations: Uninitialized scheduler fields; DI or configuration not providing a scheduler; passing the result of a GetScheduler() method that returned null; test code forgetting to wire a TestScheduler.
Related errors
- action (Value cannot be null)
- ArgumentNullException: action
- ArgumentNullException (default message: Value cannot be…
- scheduler
- scheduler (Value cannot be null)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/89a2b0f96d73226a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Async.cs:3524
/// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
/// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
/// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
/// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
/// <typeparam name="TArg15">The type of the fifteenth argument passed to the action.</typeparam>
/// <param name="action">Action to convert to an asynchronous action.</param>
/// <param name="scheduler">Scheduler to invoke the original action on.</param>
/// <returns>Asynchronous action.</returns>
/// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15> action, IScheduler scheduler)
{
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
return s_impl.ToAsync(action, scheduler);
}
/// <summary>
/// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
/// </summary>
/// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
/// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
/// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
/// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
/// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
/// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
/// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
/// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
/// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
/// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>View on GitHub (pinned to 94b5d5ab91)