dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'elementSelector')

Error message

Value cannot be null. (Parameter 'elementSelector')

What it means

This overload of Observable.ToDictionary transforms each element via elementSelector before storing it in the dictionary. The library eagerly validates arguments at call time and throws ArgumentNullException when elementSelector is null. This immediate throw keeps the failure at the exact call site instead of surfacing later on subscription.

Solutions

  1. Supply a concrete element selector, e.g. x => x.Value
  2. Guard the delegate variable for null before the call
  3. If no projection is needed, use the ToDictionary overload without elementSelector

Example fix

// before
var dict = source.ToDictionary(x => x.Id, (Func<Item, string>)null);
// after
var dict = source.ToDictionary(x => x.Id, x => x.Name);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

bool HasSelector<TSource,TElement>(Func<TSource,TElement> s) => s is not null;

Try / catch

try { var d = source.ToDictionary(k, e); }
catch (ArgumentNullException ex) when (ex.ParamName == "elementSelector") { /* fix projection */ }

Prevention

When it happens

Trigger: Calling Observable.ToDictionary(source, keySelector, elementSelector) with a null elementSelector Func<TSource,TElement>, such as an uninitialized delegate variable or a factory method that returned null.

Common situations: Conditional lambda assignment that left the variable null; passing through a wrapper API that forwards optional selectors; copy-paste of an overload call that omits the selector.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs:2906

        /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> is null.</exception>
        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
        public static IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
            where TKey : notnull
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

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

            return s_impl.ToDictionary(source, keySelector, elementSelector);
        }

        /// <summary>
        /// Creates a dictionary from an observable sequence according to a specified key selector function, a comparer, and an element selector function.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TKey">The type of the dictionary key computed for each element in the source sequence.</typeparam>
        /// <typeparam name="TElement">The type of the dictionary value computed for each element in the source sequence.</typeparam>
        /// <param name="source">An observable sequence to create a dictionary for.</param>
        /// <param name="keySelector">A function to extract a key from each element.</param>
        /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
        /// <param name="comparer">An equality comparer to compare keys.</param>
        /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="comparer"/> is null.</exception>
        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>

View on GitHub (pinned to 94b5d5ab91)