dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'selector')

Error message

Value cannot be null. (Parameter 'selector')

What it means

In Replay(source, selector, bufferSize, window, scheduler) the selector function that receives the replayed view of the source is required and must not be null. Null is rejected eagerly with ArgumentNullException (parameter 'selector').

Solutions

  1. Pass an explicit lambda to the selector parameter
  2. Initialize the delegate/strategy before use
  3. Use the non-selector Replay overload if windowing the whole source is sufficient

Example fix

// before
Func<IObservable<int>, IObservable<int>> sel = null;
var replayed = source.Replay(sel, 10, TimeSpan.FromSeconds(5), Scheduler.Default);
// after
var replayed = source.Replay(w => w.Select(x => x * 2), 10, TimeSpan.FromSeconds(5), Scheduler.Default);
Defensive patterns

Strategy: validation

Validate before calling

if (selector is null) throw new InvalidOperationException("A selector function is required for Replay with selector");

Type guard

static bool IsValidSelector<TSource, TResult>(Func<IObservable<TSource>, IObservable<TResult>> selector) => selector is not null;

Try / catch

try { var r = src.Replay(selector, size, window, scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "selector") { /* use identity selector: w => w */ }

Prevention

When it happens

Trigger: Calling source.Replay(null, bufferSize, window, scheduler); typically a lambda variable that is null because it was stored in a field/delegate and never assigned, or an accidental null literal.

Common situations: Storing query lambdas in injectable strategy objects that default to null; conditional code paths that skip selector assignment; passing a Func variable that a factory returned as null.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs:917

        /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
        /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
        /// <param name="window">Maximum time length of the replay buffer.</param>
        /// <param name="scheduler">Scheduler where connected observers within the selector function will be invoked on.</param>
        /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
        /// <seealso cref="ReplaySubject{T}"/>
        public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

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

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

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

            return s_impl.Replay(source, selector, bufferSize, window, scheduler);

View on GitHub (pinned to 94b5d5ab91)