dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

The Buffer(source, timeSpan, scheduler) overload throws ArgumentNullException when the scheduler parameter is null. This is a genuine null-reference guard: a scheduler is mandatory because the time-based buffering needs to schedule window timers. The library fails fast at call time, before any subscription.

Solutions

  1. Pass a valid scheduler, e.g. AsyncScheduler.Default (or the library's equivalent default scheduler).
  2. If the scheduler comes from DI/configuration, assert it is non-null before building the query.
  3. If a custom scheduler, verify its construction did not fail silently and return null.

Example fix

// before
var buffer = source.Buffer(TimeSpan.FromSeconds(1), GetScheduler()); // GetScheduler() returned null
// after
var sched = GetScheduler() ?? AsyncScheduler.Default;
var buffer = source.Buffer(TimeSpan.FromSeconds(1), sched);
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler is null) scheduler = AsyncScheduler.Default;
var buffered = source.Buffer(timeSpan, scheduler);

Type guard

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

Try / catch

try { var b = source.Buffer(timeSpan, scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { scheduler = AsyncScheduler.Default; var b = source.Buffer(timeSpan, scheduler); }

Prevention

When it happens

Trigger: Calling source.Buffer(timeSpan, null) explicitly, or passing a scheduler field/property that was never initialized, or a factory method returning null.

Common situations: Dependency-injection container not yet initialized when the operator is constructed, a custom IAsyncScheduler implementation whose factory returns null on failure, or copy-pasted code where the scheduler argument was removed.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs:70

                timeSpan,
                static async (source, timeSpan, observer) =>
                {
                    var (sink, timer) = await AsyncObserver.Buffer(observer, timeSpan).ConfigureAwait(false);

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

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

        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan, IAsyncScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (timeSpan < TimeSpan.Zero)
                throw new ArgumentNullException(nameof(timeSpan));
            if (scheduler == null)
                throw new ArgumentNullException(nameof(scheduler));

            return CreateAsyncObservable<IList<TSource>>.From(
                source,
                (timeSpan, scheduler),
                static async (source, state, observer) =>
                {
                    var (sink, timer) = await AsyncObserver.Buffer(observer, state.timeSpan, state.scheduler).ConfigureAwait(false);

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

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

        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

View on GitHub (pinned to 94b5d5ab91)