dotnet/reactive · error · ArgumentNullException

source

Error message

source

What it means

System.Reactive throws ArgumentNullException when the source sequence passed to Average<TSource>(IObservable<TSource>, Func<TSource,long>) is null. The operator validates the source before the selector and before returning the observable, throwing synchronously at invocation time.

Solutions

  1. Initialize the observable before calling Average
  2. Use Observable.Empty<long>() semantics via a null-coalescing fallback for absent data
  3. Fix the upstream producer to return Observable.Empty instead of null

Example fix

// before
var avg = GetTicksStream().Average(t => (long)t);
// after
var stream = GetTicksStream() ?? Observable.Empty<MyTick>();
var avg = stream.Average(t => (long)t.Ticks);
Defensive patterns

Strategy: validation

Validate before calling

if (src is null) src = Observable.Empty<TSource>();
if (selector == null) throw new ArgumentNullException(nameof(selector));

Type guard

bool HasSource<TSource>(IObservable<TSource>? s) => s is not null;

Try / catch

try { var avg = src.Average(x => (long)x.Ticks); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* fix upstream null producer */ }

Prevention

When it happens

Trigger: Calling xs.Average(x => (long)x.Ticks) where xs is null, typically because an upstream method returned null or a field was never assigned.

Common situations: Repository/service methods returning null observables on error paths; event-stream fields not yet wired; unit-test setups that forgot to initialize the subject.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs:482

            return s_impl.Average(source, selector);
        }

        /// <summary>
        /// Computes the average of an observable sequence of <see cref="long" /> values that are obtained by invoking a transform function on each element of the input sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">A sequence of values to calculate the average of.</param>
        /// <param name="selector">A transform function to apply to each element.</param>
        /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
        /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
        /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="long.MaxValue"/>.</exception>
        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
        public static IObservable<double> Average<TSource>(this IObservable<TSource> source, Func<TSource, long> selector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

            return s_impl.Average(source, selector);
        }

        /// <summary>
        /// Computes the average of an observable sequence of nullable <see cref="decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">A sequence of values to calculate the average of.</param>
        /// <param name="selector">A transform function to apply to each element.</param>
        /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>

View on GitHub (pinned to 94b5d5ab91)