dotnet/reactive · error · ArgumentNullException

continuation

Error message

continuation

What it means

The AsyncSubject.OnCompleted(Action continuation) overload throws ArgumentNullException when the continuation callback is null. The continuation is wrapped in an AwaitObserver and invoked when the subject completes, so it must be a real delegate.

Solutions

  1. Always supply a non-null continuation; use an empty lambda () => {} if no action is needed.
  2. Prefer await subject over the callback overload when using async/await.
  3. Null-check the callback before invoking OnCompleted.

Example fix

// before
subject.OnCompleted(callback); // callback may be null
// after
subject.OnCompleted(callback ?? (System.Action)(() => { }));
Defensive patterns

Strategy: validation

Validate before calling

if (continuation == null) continuation = () => { };
subject.OnCompleted(continuation);

Prevention

When it happens

Trigger: Calling AsyncSubject<T>.OnCompleted((Action)null) to await subject completion with a callback.

Common situations: Async/await bridging code where a callback variable is uninitialized or conditionally assigned.

Related errors


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

Appendix: source

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

        #region Await support

        /// <summary>
        /// Gets an awaitable object for the current AsyncSubject.
        /// </summary>
        /// <returns>Object that can be awaited.</returns>
        public AsyncSubject<T> GetAwaiter() => this;

        /// <summary>
        /// Specifies a callback action that will be invoked when the subject completes.
        /// </summary>
        /// <param name="continuation">Callback action that will be invoked when the subject completes.</param>
        /// <exception cref="ArgumentNullException"><paramref name="continuation"/> is <c>null</c>.</exception>
        public void OnCompleted(Action continuation)
        {
            if (continuation == null)
            {
                throw new ArgumentNullException(nameof(continuation));
            }

            //
            // [OK] Use of unsafe Subscribe: this type's Subscribe implementation is safe.
            //
            Subscribe/*Unsafe*/(new AwaitObserver(continuation));
        }

        private sealed class AwaitObserver : IObserver<T>
        {
            private readonly SynchronizationContext? _context;
            private readonly Action _callback;

            public AwaitObserver(Action callback)
            {
                _context = SynchronizationContext.Current;
                _callback = callback;
            }

View on GitHub (pinned to 94b5d5ab91)