dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(source));

Error message

throw new ArgumentNullException(nameof(source));

What it means

The Replay(source, selector, bufferSize, window) overload throws ArgumentNullException when the source observable is null. The library validates each argument in order before building the multicast replay subject. A null source cannot be replayed.

Solutions

  1. Initialize the source observable before composing the pipeline.
  2. Return an empty observable from factories instead of null.
  3. Defer pipeline construction until the source is available.

Example fix

// before
var result = LoadSource().Replay(sel, 10, TimeSpan.FromSeconds(5)); // LoadSource() returned null
// after
var src = LoadSource() ?? AsyncObservable.Empty<int>();
var result = src.Replay(sel, 10, TimeSpan.FromSeconds(5));
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new InvalidOperationException("source observable is not initialized");

Type guard

bool IsValidSource<TSource>(IAsyncObservable<TSource> s) => s != null;

Try / catch

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

Prevention

When it happens

Trigger: Calling source.Replay(selector, bufferSize, window) where the IAsyncObservable<TSource> argument is null; note bufferSize >= 0 and window >= 0 are checked afterwards, so the null-source error fires first.

Common situations: Chaining Replay onto a method that returned null; uninitialized stream fields; race where the source is assigned after the pipeline is built.

Related errors


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

Appendix: source

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

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

View on GitHub (pinned to 94b5d5ab91)