dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observer')

Error message

Value cannot be null. (Parameter 'observer')

What it means

RetryWhen's Subscribe validates the observer and throws ArgumentNullException("observer") when null is passed. Like RepeatWhen, the operator needs a real observer to forward source events and error/retry outcomes to.

Solutions

  1. Construct and pass a valid IObserver<T> to Subscribe.
  2. Prefer Action-based Subscribe overloads or Observer.Create<T>.
  3. Add a null guard before subscribing.

Example fix

// before
source.RetryWhen(errors => errors).Subscribe(null);
// after
source.RetryWhen(errors => errors).Subscribe(Observer.Create<T>(onNext, onError, onCompleted));
Defensive patterns

Strategy: validation

Validate before calling

// C#
if (observer is null) throw new ArgumentNullException(nameof(observer));
var sub = source.RetryWhen(e => e).Subscribe(observer);

Type guard

// C#
static bool IsValidObserver<T>(IObserver<T> o) => o is not null;

Try / catch

try { source.RetryWhen(e => e).Subscribe(observer); }
catch (ArgumentNullException ex) { Log(ex); }

Prevention

When it happens

Trigger: source.RetryWhen(errorSignals => ...).Subscribe(null), or any code path passing a null IObserver<T> into RetryWhenObservable.Subscribe.

Common situations: Observer produced by a failed factory or DI resolution returning null; uninitialized observer fields in wrapper classes.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable/RetryWhen.cs:27

namespace System.Reactive.Linq.ObservableImpl
{
    internal sealed class RetryWhen<T, U> : IObservable<T>
    {
        private readonly IObservable<T> _source;
        private readonly Func<IObservable<Exception>, IObservable<U>> _handler;

        internal RetryWhen(IObservable<T> source, Func<IObservable<Exception>, IObservable<U>> handler)
        {
            _source = source;
            _handler = handler;
        }

        public IDisposable Subscribe(IObserver<T> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var errorSignals = new Subject<Exception>();
            
            IObservable<U> redo;

            try
            {
                redo = _handler(errorSignals);

                if (redo == null)
                {
#pragma warning disable CA2201 // (Do not raise reserved exception types.) Backwards compatibility prevents us from complying.
                    throw new NullReferenceException("The handler returned a null IObservable");
#pragma warning restore CA2201
                }
            }
            catch (Exception ex)

View on GitHub (pinned to 94b5d5ab91)