dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(selector));

Error message

throw new ArgumentNullException(nameof(selector));

What it means

The Replay(source, selector, bufferSize, window) overload throws ArgumentNullException when the selector function is null. The selector consumes the replay subject to produce the result observable and is validated eagerly. This check runs after the source null check and before bufferSize/window range checks.

Solutions

  1. Pass a non-null async selector lambda for the replay subject.
  2. Fix the code path that assigns the selector delegate.
  3. Confirm argument order: source, selector, bufferSize, window.

Example fix

// before
Func<IAsyncObservable<int>, ValueTask<IAsyncObservable<int>>> selector = null;
var result = source.Replay(selector, 10, TimeSpan.FromSeconds(5));
// after
selector = async s => await s.SelectAsync(x => x);
var result = source.Replay(selector, 10, TimeSpan.FromSeconds(5));
Defensive patterns

Strategy: validation

Validate before calling

if (selector == null) throw new InvalidOperationException("selector delegate required");

Type guard

bool IsValidSelector<TSource, TResult>(Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> f) => f != null;

Try / catch

try { var r = source.Replay(sel, bufferSize, window); } catch (ArgumentNullException ex) when (ex.ParamName == "selector") { /* supply default selector */ }

Prevention

When it happens

Trigger: Calling source.Replay(null, bufferSize, window) or passing a delegate variable that was never assigned.

Common situations: Selectors built conditionally where one branch leaves the variable null; refactoring that removed the lambda; overload confusion omitting the selector argument position.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs:286

        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (selector == null)
                throw new ArgumentNullException(nameof(selector));
            if (window < TimeSpan.Zero)
                throw new ArgumentOutOfRangeException(nameof(window));
            if (scheduler == null)
                throw new ArgumentNullException(nameof(scheduler));

            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(window, scheduler)), selector);
        }

        public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window)
        {
            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));

            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(bufferSize, window)), selector);
        }

        public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window, IAsyncScheduler 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));

View on GitHub (pinned to 94b5d5ab91)