dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(scheduler));

Error message

throw new ArgumentNullException(nameof(scheduler));

What it means

The Buffer(source, timeSpan, count, scheduler) overload throws ArgumentNullException when the IScheduler is null. The scheduler drives the timed closure of buffers, so it is mandatory in this overload. Rx validates this eagerly to fail at the call site rather than at subscription time.

Solutions

  1. Pass Scheduler.Default, Scheduler.ThreadPool, Scheduler.TaskPool, or a TestScheduler in tests
  2. Register IScheduler in the DI container and verify resolution succeeds
  3. Use the non-scheduler overload Buffer(source, timeSpan, count) to get the default scheduler

Example fix

// before
IScheduler sched = container.Resolve<IScheduler>(); // may return null
var buffered = source.Buffer(TimeSpan.FromSeconds(1), 5, sched);
// after
var buffered = source.Buffer(TimeSpan.FromSeconds(1), 5, Scheduler.Default);
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler is null) throw new ArgumentNullException(nameof(scheduler));
// or: scheduler ??= Scheduler.Default;

Type guard

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

Try / catch

try { var b = source.Buffer(timeSpan, count, scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { scheduler = Scheduler.Default; /* retry */ }

Prevention

When it happens

Trigger: Calling Observable.Buffer(source, timeSpan, count, null) — typically a null scheduler from an uninitialized field, an unregistered DI service, or a helper that conditionally passes a scheduler.

Common situations: IScheduler not registered in the DI container; test scaffolding that meant to inject TestScheduler but left it null; optional scheduler parameters forwarded as null.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:246

        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (timeSpan < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(timeSpan));
            }

            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            return s_impl.Buffer(source, timeSpan, count, scheduler);
        }

        #endregion

        #endregion

        #region + Delay +

        #region TimeSpan

        /// <summary>
        /// Time shifts the observable sequence by the specified relative time duration.
        /// The relative time intervals between the values are preserved.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>

View on GitHub (pinned to 94b5d5ab91)