dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source')

Error message

Value cannot be null. (Parameter 'source')

What it means

ToDictionary(source, keySelector, valueSelector) throws ArgumentNullException for a null source at line 15, before validating the selectors. The operator aggregates the source sequence into an IDictionary<TKey, TValue>, so a null source observable cannot be subscribed. The library guards every public operator argument eagerly.

Solutions

  1. Ensure the IAsyncObservable<TSource> is created and non-null before the call.
  2. Fix the null-producing factory or field upstream.
  3. Substitute an empty async observable when the source may be absent.

Example fix

// before
var dict = src.ToDictionary(x => x.Key, x => x.Val); // src == null
// after
var s = src ?? CreateAsyncObservable<int>.Empty();
var dict = s.ToDictionary(x => x.Key, x => x.Val);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new ArgumentException("source required");
var dict = source.ToDictionary(keySelector, valueSelector);

Type guard

static bool CanBuildDict<T, K, V>(IAsyncObservable<T> s, Func<T, K> k, Func<T, V> v) => s is not null && k is not null && v is not null;

Try / catch

try { var d = source.ToDictionary(ks, vs); }
catch (ArgumentNullException ex) when (ex.ParamName is "source" or "keySelector" or "valueSelector") { /* fix args */ }

Prevention

When it happens

Trigger: Calling source.ToDictionary(keySelector, valueSelector) with source == null.

Common situations: Composing query chains where an earlier operator or factory returned null; config-driven pipelines with a missing source entry.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/ToDictionary.cs:15

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 

using System.Collections.Generic;
using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<IDictionary<TKey, TValue>> ToDictionary<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (valueSelector == null)
                throw new ArgumentNullException(nameof(valueSelector));

            return CreateAsyncObservable<IDictionary<TKey, TValue>>.From(
                source,
                (keySelector, valueSelector),
                static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.ToDictionary(observer, state.keySelector, state.valueSelector)));
        }

        public static IAsyncObservable<IDictionary<TKey, TValue>> ToDictionary<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector, IEqualityComparer<TKey> comparer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (valueSelector == null)

View on GitHub (pinned to 94b5d5ab91)