dotnet/reactive · error · ArgumentNullException

error

Error message

error

What it means

BehaviorSubject.OnError throws ArgumentNullException when the error parameter is null. Like all Rx subjects, it enforces the contract that OnError carries a non-null exception before forwarding it to subscribers.

Solutions

  1. Pass a real exception instance; wrap unknown failures explicitly.
  2. Null-check the exception before calling OnError.
  3. Prefer OnErrorResumeNext or Catch operators to convert nulls/absent errors into typed failures.

Example fix

// before
subject.OnError(task.Exception);
// after
subject.OnError(task.Exception ?? new InvalidOperationException("task failed without exception"));
Defensive patterns

Strategy: validation

Validate before calling

if (error != null) subject.OnError(error);

Prevention

When it happens

Trigger: Calling BehaviorSubject<T>.OnError(null) from a source wrapper or exception-forwarding lambda.

Common situations: Forwarding Task.Exception from a non-faulted task; UI event handlers with null error payloads.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Subjects/BehaviorSubject.cs:167

            if (os != null)
            {
                foreach (var o in os)
                {
                    o.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));
            }

            IObserver<T>[]? os = null;

            lock (_gate)
            {
                CheckDisposed();

                if (!_isStopped)
                {
                    os = _observers.Data;
                    _observers = ImmutableList<IObserver<T>>.Empty;
                    _isStopped = true;
                    _exception = error;
                }
            }

            if (os != null)

View on GitHub (pinned to 94b5d5ab91)