dotnet/reactive · error · ArgumentNullException

source (Parameter 'source')

Error message

source (Parameter 'source')

What it means

The ToAsyncAction extension method converts an IObservable<TSource> into a WinRT IAsyncAction. It throws ArgumentNullException with parameter name 'source' when called on a null observable, because there is nothing to convert.

Solutions

  1. Check that the observable is non-null before calling ToAsyncAction
  2. Use the null-coalescing operator to supply a default (e.g. Observable.Empty<TSource>())
  3. Fix the upstream code that produced the null observable

Example fix

// before
var action = maybeNull.ToAsyncAction();
// after
var action = (maybeNull ?? Observable.Empty<TSource>()).ToAsyncAction();
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new ArgumentNullException(nameof(source));

Type guard

static bool IsValidSource<TSource>(IObservable<TSource>? source) => source is not null;

Try / catch

try { action = source.ToAsyncAction(); } catch (ArgumentNullException ex) when (ex.ParamName == "source") { action = Observable.Empty<TSource>().ToAsyncAction(); }

Prevention

When it happens

Trigger: Invoking source.ToAsyncAction() where source is a null IObservable<TSource> reference.

Common situations: Chaining conversions from a nullable field/return value, e.g. a factory method that returned null before the conversion, or a misconfigured service locator yielding null.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/AsyncInfoObservable.cs:34

    /// </summary>
    [CLSCompliant(false)]
    public static class AsyncInfoObservable
    {
        #region IAsyncAction

        /// <summary>
        /// Creates a Windows Runtime asynchronous action that represents the completion of the observable sequence.
        /// Upon cancellation of the asynchronous action, the subscription to the source sequence will be disposed.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to expose as an asynchronous action.</param>
        /// <returns>Windows Runtime asynchronous action object representing the completion of the observable sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IAsyncAction ToAsyncAction<TSource>(this IObservable<TSource> source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return AsyncInfo.Run(ct => (Task)source.DefaultIfEmpty().ToTask(ct));
        }

        #region Progress

        /// <summary>
        /// Creates a Windows Runtime asynchronous action that represents the completion of the observable sequence, reporting incremental progress for each element produced by the sequence.
        /// Upon cancellation of the asynchronous action, the subscription to the source sequence will be disposed.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to expose as an asynchronous action.</param>
        /// <returns>Windows Runtime asynchronous action object representing the completion of the observable sequence, reporting incremental progress for each source sequence element.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IAsyncActionWithProgress<int> ToAsyncActionWithProgress<TSource>(this IObservable<TSource> source)
        {
            if (source == null)

View on GitHub (pinned to 94b5d5ab91)