dotnet/reactive · error · ArgumentNullException

error

Error message

error

What it means

AsyncSubject.OnError caches and replays the terminal error to all current and future observers; a null error is invalid because subscribers must receive an actual exception, so it is validated. Fix: call OnCompleted instead if the sequence ends without error.

Solutions

  1. Pass a concrete Exception; wrap unknown failures in a new Exception or OperationCanceledException.
  2. Null-check before calling OnError in source/wrapper code.
  3. Use OnError(new AggregateException(inner)) if aggregating multiple failures.

Example fix

// before
subject.OnError(ex); // ex may be null
// after
if (ex != null) subject.OnError(ex); else subject.OnError(new InvalidOperationException("unknown failure"));
Defensive patterns

Strategy: validation

Validate before calling

if (error == null) subject.OnError(new InvalidOperationException("source failed without exception")); else subject.OnError(error);

Prevention

When it happens

Trigger: Calling AsyncSubject<T>.OnError(null), often from source wrappers that pass along a null exception from underlying streams.

Common situations: Custom IObservable sources forwarding a null Exception from Task.Exception or from event handlers that capture no error.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Subjects/AsyncSubject.cs:125

                        foreach (var observer in observers)
                        {
                            observer.Observer?.OnCompleted();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Notifies all subscribed observers about the exception.
        /// </summary>
        /// <param name="error">The exception to send to all observers.</param>
        /// <exception cref="ArgumentNullException"><paramref name="error"/> is <c>null</c>.</exception>
        public override void OnError(Exception error)
        {
            if (error == null)
            {
                throw new ArgumentNullException(nameof(error));
            }

            for (; ; )
            {
                var observers = Volatile.Read(ref _observers);

                if (observers == Disposed)
                {
                    _exception = null;
                    _value = default;
                    ThrowDisposed();
                    break;
                }

                if (observers == Terminated)
                {
                    break;
                }

View on GitHub (pinned to 94b5d5ab91)