dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

The Take(source, duration, scheduler) overload of System.Reactive.Async requires a non-null IAsyncScheduler. The guard at Take.cs:66 throws ArgumentNullException because the scheduler parameter is null; the library refuses null dependencies up front rather than failing later during subscription.

Solutions

  1. Pass a concrete scheduler such as TaskPoolAsyncScheduler.Default or NewThreadAsyncScheduler.Default.
  2. If using DI, register IAsyncScheduler in the container and verify resolution returns non-null.
  3. If you intended immediate/synchronous behavior, use a scheduler implementation suited to that instead of null.
  4. If the duration is TimeSpan.Zero, use Empty<TSource>() directly so no scheduler is needed.

Example fix

// before: AsyncObservable.Take(source, TimeSpan.FromSeconds(1), null)  // after: AsyncObservable.Take(source, TimeSpan.FromSeconds(1), TaskPoolAsyncScheduler.Default)
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new ArgumentNullException(nameof(source)); if (duration < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(duration)); if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); var result = AsyncObservable.Take(source, duration, scheduler);

Type guard

static bool IsValidTakeWindow<TSource>(IAsyncObservable<TSource> s, TimeSpan d, IAsyncScheduler sch) => s != null && d >= TimeSpan.Zero && sch != null;

Try / catch

try { var res = AsyncObservable.Take(source, duration, scheduler); } catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { scheduler = TaskPoolAsyncScheduler.Default; var res = AsyncObservable.Take(source, duration, scheduler); }

Prevention

When it happens

Trigger: Calling AsyncObservable.Take(source, TimeSpan, null), or passing a scheduler field/property that was never initialized (e.g. a DI-resolved scheduler that is null).

Common situations: DI container not registered for IAsyncScheduler; refactoring that removed a scheduler instantiation; copying an overload call and forgetting the third argument.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Take.cs:66

                duration,
                static async (source, duration, observer) =>
                {
                    var (sourceObserver, timer) = await AsyncObserver.Take(observer, duration).ConfigureAwait(false);

                    var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);

                    return StableCompositeAsyncDisposable.Create(subscription, timer);
                });
        }

        public static IAsyncObservable<TSource> Take<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration, IAsyncScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (duration < TimeSpan.Zero)
                throw new ArgumentOutOfRangeException(nameof(duration));
            if (scheduler == null)  // REVIEW: scheduler not used.
                throw new ArgumentNullException(nameof(scheduler));

            if (duration == TimeSpan.Zero)
            {
                return Empty<TSource>();
            }

            // REVIEW: May be easier to just use TakeUntil with a Timer parameter. Do we want Take on the observer?

            return CreateAsyncObservable<TSource>.From(
                source,
                (duration, scheduler),
                static async (source, state, observer) =>
                {
                    var (sourceObserver, timer) = await AsyncObserver.Take(observer, state.duration).ConfigureAwait(false);

                    var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);

                    return StableCompositeAsyncDisposable.Create(subscription, timer);

View on GitHub (pinned to 94b5d5ab91)