dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observableFactoryAsync')

Error message

Value cannot be null. (Parameter 'observableFactoryAsync')

What it means

The async Observable.Using overload requires an observableFactoryAsync delegate that consumes the resource and a CancellationToken to produce the Task<IObservable<TResult>>. A null value is rejected with ArgumentNullException at call time.

Solutions

  1. Pass a valid async lambda, e.g. async (res, ct) => UseResourceAsync(res, ct)
  2. Verify delegate-producing helpers never return null
  3. Use Observable.Empty<TResult>() inside the factory for no-op cases instead of null

Example fix

// before
Observable.Using(ct => OpenResourceAsync(ct), null);
// after
Observable.Using(ct => OpenResourceAsync(ct), (res, ct) => UseResourceAsync(res, ct));
Defensive patterns

Strategy: validation

Validate before calling

if (resourceFactoryAsync == null || observableFactoryAsync == null) throw new ArgumentNullException(observableFactoryAsync == null ? nameof(observableFactoryAsync) : nameof(resourceFactoryAsync));
var seq = Observable.Using(resourceFactoryAsync, observableFactoryAsync);

Type guard

static bool HasAsyncObservableFactory<TResource, TResult>(Func<TResource, CancellationToken, Task<IObservable<TResult>>> f) where TResource : IDisposable => f is not null;

Try / catch

try
{
    var seq = Observable.Using(resourceFactoryAsync, observableFactoryAsync);
}
catch (ArgumentNullException ex) when (ex.ParamName == "observableFactoryAsync")
{
    throw new InvalidOperationException("An async observable factory is required", ex);
}

Prevention

When it happens

Trigger: Calling Observable.Using(resourceFactoryAsync, observableFactoryAsync) with a null Func<TResource, CancellationToken, Task<IObservable<TResult>>> as the second argument.

Common situations: Conditionally built async lambdas that were never assigned; wrapper APIs forwarding nulls; refactoring from the sync overload where the delegate names changed but assignments did not.

Related errors


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

Appendix: source

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

        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
        /// <typeparam name="TResource">The type of the resource used during the generation of the resulting sequence. Needs to implement <see cref="IDisposable"/>.</typeparam>
        /// <param name="resourceFactoryAsync">Asynchronous factory function to obtain a resource object.</param>
        /// <param name="observableFactoryAsync">Asynchronous factory function to obtain an observable sequence that depends on the obtained resource.</param>
        /// <returns>An observable sequence whose lifetime controls the lifetime of the dependent resource object.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="resourceFactoryAsync"/> or <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 resource factory and observable factory functions will be signaled.</remarks>
        public static IObservable<TResult> Using<TResult, TResource>(Func<CancellationToken, Task<TResource>> resourceFactoryAsync, Func<TResource, CancellationToken, Task<IObservable<TResult>>> observableFactoryAsync) where TResource : IDisposable
        {
            if (resourceFactoryAsync == null)
            {
                throw new ArgumentNullException(nameof(resourceFactoryAsync));
            }

            if (observableFactoryAsync == null)
            {
                throw new ArgumentNullException(nameof(observableFactoryAsync));
            }

            return s_impl.Using(resourceFactoryAsync, observableFactoryAsync);
        }

        #endregion
    }
}

View on GitHub (pinned to 94b5d5ab91)