dotnet/reactive · error · ArgumentNullException
throw new ArgumentNullException(nameof(scheduler));
Error message
throw new ArgumentNullException(nameof(scheduler));
What it means
The Throw operator validates that both the error to emit and the scheduler used to schedule the emission are non-null. Passing a null IAsyncScheduler means the operator cannot schedule OnErrorAsync, so it fails fast with ArgumentNullException instead of failing later inside the scheduled work. This is standard eager argument validation performed synchronously when Throw is called.
Solutions
- Pass a concrete non-null IAsyncScheduler, e.g. ImmediateAsyncScheduler.Instance or a TestAsyncScheduler instance
- Check the code path producing the scheduler value and fix the null source (missing DI registration, failed lookup)
- If no scheduling is needed, use the Throw(error) overload that defaults to the immediate scheduler
Example fix
// before
var obs = AsyncObservable.Throw<int>(new Exception("boom"), scheduler); // scheduler is null
// after
var obs = AsyncObservable.Throw<int>(new Exception("boom"), scheduler ?? ImmediateAsyncScheduler.Instance); Defensive patterns
Strategy: validation
Validate before calling
if (error == null) throw new ArgumentNullException(nameof(error)); if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); var obs = AsyncObservable.Throw<int>(error, scheduler);
Type guard
bool IsValidScheduler(IAsyncScheduler s) => s is not null;
Try / catch
try
{
var obs = AsyncObservable.Throw<int>(error, scheduler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler")
{
// fall back to immediate scheduler
var obs = AsyncObservable.Throw<int>(error, ImmediateAsyncScheduler.Instance);
} Prevention
- Default to ImmediateAsyncScheduler.Instance when no scheduler is needed
- Assert non-null scheduler at application startup / DI validation
- Avoid nullable scheduler variables; resolve eagerly
When it happens
Trigger: Calling AsyncObservable.Throw<TSource>(error, scheduler) with a null scheduler argument, e.g. a scheduler variable that was never initialized or a factory method that returned null.
Common situations: Developers resolving the scheduler from DI/configuration where registration is missing; passing the result of a lookup that returns null; refactoring code that previously used ImmediateAsyncScheduler.Instance.
Related errors
- throw new ArgumentNullException(nameof(scheduler));
- null (Parameter 'scheduler')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'values')
- Value cannot be null. (Parameter 'scheduler')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/1f19c67a3b2263a5.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Throw.cs:25
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Throw<TSource>(Exception error)
{
if (error == null)
throw new ArgumentNullException(nameof(error));
return Create<TSource>(observer => AsyncObserver.Throw(observer, error));
}
public static IAsyncObservable<TSource> Throw<TSource>(Exception error, IAsyncScheduler scheduler)
{
if (error == null)
throw new ArgumentNullException(nameof(error));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return Create<TSource>(observer => AsyncObserver.Throw(observer, error, scheduler));
}
}
public partial class AsyncObserver
{
public static ValueTask<IAsyncDisposable> Throw<TSource>(IAsyncObserver<TSource> observer, Exception error) => Throw(observer, error, ImmediateAsyncScheduler.Instance);
public static ValueTask<IAsyncDisposable> Throw<TSource>(IAsyncObserver<TSource> observer, Exception error, IAsyncScheduler scheduler)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return scheduler.ScheduleAsync(async ct =>
{View on GitHub (pinned to 94b5d5ab91)