dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'disposeScheduler')

Error message

Value cannot be null. (Parameter 'disposeScheduler')

What it means

In the same three-argument overload, the disposeScheduler null check at line 38 throws ArgumentNullException. Disposal of the subscription is scheduled on this scheduler; a null value would break cleanup, so the guard rejects it eagerly. This is the last of the three checks in the overload.

Solutions

  1. Provide a non-null IAsyncScheduler for disposeScheduler.
  2. Use source.ToAsyncObservable(scheduler) to use one scheduler for both subscribe and dispose.
  3. Use the parameterless overload to accept TaskPoolAsyncScheduler.Default for both.

Example fix

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

Strategy: validation

Validate before calling

if (disposeScheduler is null) disposeScheduler = TaskPoolAsyncScheduler.Default;
var async = source.ToAsyncObservable(subscribeScheduler, disposeScheduler);

Type guard

static bool HasDisposeScheduler(IAsyncScheduler d) => d is not null;

Try / catch

try { var a = source.ToAsyncObservable(sub, disp); }
catch (ArgumentNullException ex) when (ex.ParamName == "disposeScheduler") { /* supply scheduler */ }

Prevention

When it happens

Trigger: Calling source.ToAsyncObservable(subscribeScheduler, null).

Common situations: Copy-paste of the subscribe-only overload call and leaving the second argument null; incomplete migration when the dispose scheduler concept was added.

Related errors


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

Appendix: source

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

        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 =>
                {
                    ct.ThrowIfCancellationRequested();

                    var disposable = source.Subscribe(AsyncObserver.ToObserver(observer));

                    var disposeTask = AsyncDisposable.Create(() => disposeScheduler.ExecuteAsync(_ =>
                    {
                        disposable.Dispose();
                        return default;
                    }));

                    await d.AddAsync(disposeTask).RendezVous(subscribeScheduler);

View on GitHub (pinned to 94b5d5ab91)