dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'sources')

Error message

Value cannot be null. (Parameter 'sources')

What it means

Case requires a dictionary mapping selector values to sequences. When the sources dictionary is null, the operator throws ArgumentNullException with parameter name 'sources' during the eager argument check, before enumeration.

Solutions

  1. Pass a non-null IDictionary<TValue, IEnumerable<TResult>> (use an empty dictionary if no cases)
  2. Verify the code path that constructs the dictionary
  3. If an empty mapping is intentional, pass new Dictionary<...>() rather than null

Example fix

// before
IDictionary<int, IEnumerable<int>> map = TryLoadMap(); // may be null
var seq = Case(getKey, map);
// after
var seq = Case(getKey, TryLoadMap() ?? new Dictionary<int, IEnumerable<int>>());
Defensive patterns

Strategy: validation

Validate before calling

if (sources == null) sources = new Dictionary<TValue, IEnumerable<TResult>>();

Type guard

bool IsValidCaseCall<TValue,TResult>(IDictionary<TValue, IEnumerable<TResult>> sources) => sources != null;

Try / catch

try { seq = Case(selector, sources); } catch (ArgumentNullException ex) when (ex.ParamName == "sources") { seq = Enumerable.Empty<TResult>(); }

Prevention

When it happens

Trigger: Calling Case<TValue,TResult>(selector, null) or the overload Case(selector, null, defaultSource) with a null sources dictionary.

Common situations: Dictionary built conditionally or loaded from configuration that failed and returned null; variable shadowing leaving the map uninitialized.

Related errors


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

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Case.cs:24

namespace System.Linq
{
    public static partial class EnumerableEx
    {
        /// <summary>
        /// Returns a sequence from a dictionary based on the result of evaluating a selector function.
        /// </summary>
        /// <typeparam name="TValue">Type of the selector value.</typeparam>
        /// <typeparam name="TResult">Result sequence element type.</typeparam>
        /// <param name="selector">Selector function used to pick a sequence from the given sources.</param>
        /// <param name="sources">Dictionary mapping selector values onto resulting sequences.</param>
        /// <returns>The source sequence corresponding with the evaluated selector value; otherwise, an empty sequence.</returns>
        public static IEnumerable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IEnumerable<TResult>> sources)
        {
            if (selector == null)
                throw new ArgumentNullException(nameof(selector));
            if (sources == null)
                throw new ArgumentNullException(nameof(sources));

            return Case(selector, sources, []);
        }

        /// <summary>
        /// Returns a sequence from a dictionary based on the result of evaluating a selector function, also specifying a
        /// default sequence.
        /// </summary>
        /// <typeparam name="TValue">Type of the selector value.</typeparam>
        /// <typeparam name="TResult">Result sequence element type.</typeparam>
        /// <param name="selector">Selector function used to pick a sequence from the given sources.</param>
        /// <param name="sources">Dictionary mapping selector values onto resulting sequences.</param>
        /// <param name="defaultSource">
        /// Default sequence to return in case there's no corresponding source for the computed
        /// selector value.
        /// </param>
        /// <returns>The source sequence corresponding with the evaluated selector value; otherwise, the default source.</returns>
        public static IEnumerable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IEnumerable<TResult>> sources, IEnumerable<TResult> defaultSource)

View on GitHub (pinned to 94b5d5ab91)