dotnet/reactive · error · ArgumentNullException

nameof(observableFactoryAsync)

Error message

nameof(observableFactoryAsync)

What it means

This Defer overload uses an asynchronous factory Func<Task<IObservable<TResult>>> plus ignoreExceptionsAfterUnsubscribe. The factory must be non-null; Rx throws ArgumentNullException at composition time rather than letting the first subscription throw.

Solutions

  1. Pass a non-null async factory returning Task<IObservable<TResult>>.
  2. Null-check the factory delegate before calling Defer.
  3. Fix the producer that returns null instead of a delegate.

Example fix

// before
var obs = Observable.Defer(asyncFactory, ignoreAfterUnsub); // asyncFactory null
// after
var obs = Observable.Defer(asyncFactory ?? (async () => Observable.Empty<int>()), ignoreAfterUnsub);
Defensive patterns

Strategy: validation

Validate before calling

if (observableFactoryAsync is null) throw new ArgumentNullException(nameof(observableFactoryAsync));
var obs = Observable.Defer(observableFactoryAsync, ignoreExceptionsAfterUnsubscribe);

Type guard

bool IsValid<T>(Func<Task<IObservable<T>>> f) => f is not null;

Try / catch

try { var obs = Observable.Defer(observableFactoryAsync, ignore); }
catch (ArgumentNullException ex) when (ex.ParamName == "observableFactoryAsync") { /* use sync Defer fallback */ }

Prevention

When it happens

Trigger: Calling Observable.Defer<TResult>(observableFactoryAsync, ignoreExceptionsAfterUnsubscribe) with a null Func<Task<IObservable<TResult>>> argument.

Common situations: An async factory method group resolved via reflection returning null, an unassigned delegate field, or a settings-driven factory that is null when async creation is disabled.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Creation.cs:232

        /// <summary>
        /// Returns an observable sequence that starts the specified asynchronous factory function whenever a new observer subscribes.
        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
        /// <param name="observableFactoryAsync">Asynchronous factory function to start for each observer that subscribes to the resulting sequence.</param>
        /// <param name="ignoreExceptionsAfterUnsubscribe">
        /// If true, exceptions that occur after cancellation has been initiated by unsubscribing from the observable
        /// this method returns will be handled and silently ignored. If false, they will go unobserved, meaning they
        /// will eventually emerge through <see cref="TaskScheduler.UnobservedTaskException"/>.
        /// </param>
        /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="observableFactoryAsync"/> is null.</exception>
        /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
        public static IObservable<TResult> Defer<TResult>(Func<Task<IObservable<TResult>>> observableFactoryAsync, bool ignoreExceptionsAfterUnsubscribe)
        {
            if (observableFactoryAsync == null)
            {
                throw new ArgumentNullException(nameof(observableFactoryAsync));
            }

            return s_impl.Defer(observableFactoryAsync, ignoreExceptionsAfterUnsubscribe);
        }

        /// <summary>
        /// Returns an observable sequence that starts the specified cancellable asynchronous factory function whenever a new observer subscribes.
        /// The CancellationToken passed to the asynchronous factory function is tied to the returned disposable subscription, allowing best-effort cancellation.
        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
        /// <param name="observableFactoryAsync">Asynchronous factory function to start for each observer that subscribes to the resulting sequence.</param>
        /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="observableFactoryAsync"/> is null.</exception>
        /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
        /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous observable factory function will be signaled.</remarks>
        public static IObservable<TResult> DeferAsync<TResult>(Func<CancellationToken, Task<IObservable<TResult>>> observableFactoryAsync)
        {
            return DeferAsync(observableFactoryAsync, ignoreExceptionsAfterUnsubscribe: false);

View on GitHub (pinned to 94b5d5ab91)