dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(source));

Error message

throw new ArgumentNullException(nameof(source));

What it means

The Scan<TSource>(source, func) operator throws ArgumentNullException when the source async observable is null. Scan aggregates emissions with an accumulator, so it validates the source synchronously at call time (the func is validated immediately after) before building the operator.

Solutions

  1. Create the source observable before calling Scan
  2. Coalesce to an empty stream: source ?? AsyncObservable.Empty<TSource>()
  3. Guard and throw a descriptive exception in your composition helper
  4. Fix the upstream method that returns null for the source

Example fix

// before
var total = events.Scan((acc, x) => acc + x); // events null
// after
var src = events ?? AsyncObservable.Empty<int>();
var total = src.Scan((acc, x) => acc + x);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new ArgumentNullException(nameof(source));
var scanned = source.Scan((acc, x) => acc + x);

Type guard

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

Try / catch

try
{
    var scanned = source.Scan(accumulate);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source")
{
    scanned = AsyncObservable.Empty<TSource>();
}

Prevention

When it happens

Trigger: Calling source.Scan(accumulator) with a null source — an uninitialized stream, a factory that returned null, or applying Scan to the result of a lookup/conditional that missed.

Common situations: Running totals over a stream whose producer failed silently; pipeline builders where an earlier operator conditionally returned null; tests where the subject was never assigned.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Scan.cs:14

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 

using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<TSource> Scan<TSource>(this IAsyncObservable<TSource> source, Func<TSource, TSource, TSource> func)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (func == null)
                throw new ArgumentNullException(nameof(func));

            return CreateAsyncObservable<TSource>.From(
                source,
                func,
                static (source, func, observer) => source.SubscribeSafeAsync(AsyncObserver.Scan(observer, func)));
        }

        public static IAsyncObservable<TSource> Scan<TSource>(this IAsyncObservable<TSource> source, Func<TSource, TSource, ValueTask<TSource>> func)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (func == null)
                throw new ArgumentNullException(nameof(func));

            return CreateAsyncObservable<TSource>.From(
                source,

View on GitHub (pinned to 94b5d5ab91)