dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(source));

Error message

throw new ArgumentNullException(nameof(source));

What it means

The parameterless Retry(source) operator validates its input and throws ArgumentNullException when source is null. Retry works by re-subscribing to the given observable on failure, so a null source leaves nothing to subscribe to and the guard fires before the operator is created.

Solutions

  1. Guarantee the source observable is initialized before calling Retry.
  2. Make source factories throw or return non-null fallback observables (e.g. AsyncObservable.Empty<T>()).
  3. Coalesce: source ?? throw new InvalidOperationException(...) or a default empty source.

Example fix

// before
var retried = AsyncObservable.Retry(GetSource()); // may return null
// after
var src = GetSource() ?? AsyncObservable.Empty<int>();
var retried = AsyncObservable.Retry(src);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new InvalidOperationException("Retry requires a non-null source observable");

Type guard

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

Try / catch

try { var retried = AsyncObservable.Retry(source); } catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* fix source provisioning */ }

Prevention

When it happens

Trigger: Calling AsyncObservable.Retry(null) with a source that came from a null-returning factory, an unset field, or a failed lookup.

Common situations: Chained pipeline construction where an earlier operator returned null on error; service-locator lookups returning null; optional streams that were never assigned.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Retry.cs:15

// 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.Linq;
using System.Reactive.Disposables;

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

            return Create(
                source,
                async static (source, observer) =>
                {
                    var (sink, inner) = AsyncObserver.Retry(observer, source);

                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);

                    return StableCompositeAsyncDisposable.Create(subscription, inner);
                });
        }

        public static IAsyncObservable<TSource> Retry<TSource>(this IAsyncObservable<TSource> source, int retryCount)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (retryCount < 0)

View on GitHub (pinned to 94b5d5ab91)