dotnet/reactive · error · ArgumentNullException

ArgumentNullException(nameof(source))

Error message

ArgumentNullException(nameof(source))

What it means

The Do extension method Do<TSource>(this IAsyncObservable<TSource> source, IObserver<TSource> observer) throws ArgumentNullException when source is null. Do is a side-effect tap over a source sequence; there is nothing to tap into if the source is null, so it fails fast at composition time.

Solutions

  1. Ensure the source IAsyncObservable<TSource> is non-null before calling Do (check how it was constructed).
  2. If the source may be absent, coalesce to an empty observable via AsyncObservable.Empty<TSource>() rather than null.
  3. Null-check or throw a meaningful exception at the pipeline-building site.

Example fix

// before
var tapped = pipeline?.Do(spyObserver); // pipeline null -> ArgumentNullException
// after
var tapped = (pipeline ?? AsyncObservable.Empty<int>()).Do(spyObserver);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new InvalidOperationException("source observable must be built before Do");
var tapped = source.Do(observer);

Type guard

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

Try / catch

try { var tapped = source.Do(observer); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* rebuild the source pipeline */ }

Prevention

When it happens

Trigger: Invoking source.Do(observer) as an extension on a null IAsyncObservable<TSource>, or calling AsyncObservable.Do(null, observer) directly.

Common situations: An observable factory/config-driven pipeline that produced null; operator chains where an earlier step returned null instead of a sequence; nullable field holding the pipeline never initialized.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Do.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> Do<TSource>(this IAsyncObservable<TSource> source, IObserver<TSource> observer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));

            return Create(
                source,
                observer,
                static (source, observer, target) => source.SubscribeSafeAsync(AsyncObserver.Do(target, observer)));
        }

        public static IAsyncObservable<TSource> Do<TSource>(this IAsyncObservable<TSource> source, Action<TSource> onNext)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (onNext == null)
                throw new ArgumentNullException(nameof(onNext));

            return Create(
                source,

View on GitHub (pinned to 94b5d5ab91)