dotnet/reactive · error · ArgumentNullException
nameof(scheduler)
Error message
nameof(scheduler)
What it means
Observable.Empty<TResult>(IScheduler) emits the completion notification on the supplied scheduler, which must be non-null. Rx throws ArgumentNullException to ensure the scheduling behavior is explicit; without a scheduler the parameterless overload should be used instead.
Solutions
- Pass a concrete scheduler such as Scheduler.Default, Scheduler.Immediate, or Scheduler.CurrentThread.
- Use the parameterless Observable.Empty<TResult>() when no custom scheduling is needed.
- Null-check the scheduler before calling and substitute Scheduler.Default when null.
Example fix
// before var obs = Observable.Empty<int>(scheduler); // scheduler null // after var obs = Observable.Empty<int>(scheduler ?? Scheduler.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler is null) throw new ArgumentNullException(nameof(scheduler)); var obs = Observable.Empty<int>(scheduler);
Type guard
bool IsValid(IScheduler s) => s is not null;
Try / catch
try { var obs = Observable.Empty<int>(scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { obs = Observable.Empty<int>(); } Prevention
- Default null schedulers to Scheduler.Default at the entry point
- Use the parameterless Observable.Empty<T>() when no custom scheduler is needed
- Make IScheduler a required constructor dependency so DI fails fast
When it happens
Trigger: Calling Observable.Empty<TResult>(scheduler) with a null IScheduler, typically when the scheduler comes from a nullable parameter, property, or service that was not provided.
Common situations: Test code where Scheduler defaults were not injected, DI misconfiguration returning null for IScheduler, or a wrapper API forwarding a null scheduler.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/db2af8d265ca08b3.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Creation.cs:316
#pragma warning disable IDE0060 // (Remove unused parameter.) Required for type inference
public static IObservable<TResult> Empty<TResult>(TResult witness)
#pragma warning restore IDE0060
{
return s_impl.Empty<TResult>(); // Pure inference - no specialized target method.
}
/// <summary>
/// Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
/// </summary>
/// <typeparam name="TResult">The type used for the <see cref="IObservable{T}"/> type parameter of the resulting sequence.</typeparam>
/// <param name="scheduler">Scheduler to send the termination call on.</param>
/// <returns>An observable sequence with no elements.</returns>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
public static IObservable<TResult> Empty<TResult>(IScheduler scheduler)
{
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
return s_impl.Empty<TResult>(scheduler);
}
/// <summary>
/// Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
/// </summary>
/// <typeparam name="TResult">The type used for the <see cref="IObservable{T}"/> type parameter of the resulting sequence.</typeparam>
/// <param name="scheduler">Scheduler to send the termination call on.</param>
/// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
/// <returns>An observable sequence with no elements.</returns>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
#pragma warning disable IDE0060 // (Remove unused parameter.) Required for type inference
public static IObservable<TResult> Empty<TResult>(IScheduler scheduler, TResult witness)
#pragma warning restore IDE0060
{
if (scheduler == null)View on GitHub (pinned to 94b5d5ab91)