dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

In ToAsyncObservable(source, scheduler), the scheduler parameter is null-checked at line 26 after the source check. The scheduler drives subscription/dispatch work, so a null would break scheduling later; the library throws immediately. Passing IAsyncScheduler.Default or TaskPoolAsyncScheduler.Default is the intended usage.

Solutions

  1. Pass TaskPoolAsyncScheduler.Default or another valid IAsyncScheduler instance.
  2. If using a custom scheduler, verify it is constructed before subscription.
  3. Use the parameterless overload or the (source) overload to get default schedulers.

Example fix

// before
var async = source.ToAsyncObservable(null);
// after
var async = source.ToAsyncObservable(TaskPoolAsyncScheduler.Default);
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler is null) scheduler = TaskPoolAsyncScheduler.Default;
var async = source.ToAsyncObservable(scheduler);

Type guard

static bool HasScheduler(IAsyncScheduler s) => s is not null;

Try / catch

try { var a = source.ToAsyncObservable(scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* default scheduler */ }

Prevention

When it happens

Trigger: Calling source.ToAsyncObservable(null); a scheduler field resolved from configuration/DI that is null.

Common situations: Custom IAsyncScheduler implementation not registered; refactoring removed the scheduler initialization; confusion between sync IScheduler and IAsyncScheduler types.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/d90be9b45a60fa84. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/ToAsyncObservable.cs:26

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<TSource> ToAsyncObservable<TSource>(this IObservable<TSource> source)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            return ToAsyncObservable(source, TaskPoolAsyncScheduler.Default, TaskPoolAsyncScheduler.Default);
        }

        public static IAsyncObservable<TSource> ToAsyncObservable<TSource>(this IObservable<TSource> source, IAsyncScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (scheduler == null)
                throw new ArgumentNullException(nameof(scheduler));

            return ToAsyncObservable(source, scheduler, scheduler);
        }

        public static IAsyncObservable<TSource> ToAsyncObservable<TSource>(this IObservable<TSource> source, IAsyncScheduler subscribeScheduler, IAsyncScheduler disposeScheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (subscribeScheduler == null)
                throw new ArgumentNullException(nameof(subscribeScheduler));
            if (disposeScheduler == null)
                throw new ArgumentNullException(nameof(disposeScheduler));

            return Create<TSource>(async observer =>
            {
                var d = new CompositeAsyncDisposable();

                var subscribeTask = await subscribeScheduler.ScheduleAsync(async ct =>

View on GitHub (pinned to 94b5d5ab91)