dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'sources')
Error message
Value cannot be null. (Parameter 'sources')
What it means
Thrown by Case<TValue, TResult>(selector, sources, defaultSource) when the sources dictionary is null. Case looks up the selector's value in this IDictionary to choose the source observable; without the dictionary there is nothing to dispatch to, so the operator rejects null eagerly.
Solutions
- Build and pass a non-empty sources dictionary (keys matching selector outputs).
- Ensure the registry/dictionary is initialized before composing the pipeline.
- Use the dictionary-preserving overload Case(selector, sources, scheduler) if a default isn't needed, but still pass a non-null map.
Example fix
// before var stream = Case(selector, sourceMap, empty); // sourceMap null before init // after var map = sourceMap ?? new Dictionary<Key, IAsyncObservable<Result>>(); var stream = Case(selector, map, empty);
Defensive patterns
Strategy: validation
Validate before calling
if (sources is null) throw new ArgumentNullException(nameof(sources));
Type guard
bool HasSources<TValue, TResult>(IDictionary<TValue, IAsyncObservable<TResult>>? d) => d is { Count: > 0 }; Try / catch
try { var s = Case(selector, sources, defaultSource); }
catch (ArgumentNullException ex) when (ex.ParamName == "sources") { /* initialize registry */ } Prevention
- Populate the sources dictionary before building pipelines that use it
- Fail fast at startup if the source registry is empty or null
- Use Lazy<T>/initialization guards for lazily built registries
When it happens
Trigger: Calling Case(selector, sources, defaultSource) with a null IDictionary<TValue, IAsyncObservable<TResult>>, often a dictionary built lazily or from a config registry that failed to load.
Common situations: Source registry populated at startup but accessed before initialization; DI not providing the mapping; refactoring renamed the dictionary field leaving it null.
Related errors
- Value cannot be null. (Parameter 'selector')
- Value cannot be null. (Parameter 'defaultSource')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'error')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/6c8dff2bd347230c.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Case.cs:22
using System.Collections.Generic;
using System.Reactive.Concurrency;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources) => Case(selector, sources, Empty<TResult>());
public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources, IAsyncScheduler scheduler) => Case(selector, sources, Empty<TResult>(scheduler));
public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources, IAsyncObservable<TResult> defaultSource)
{
if (selector == null)
throw new ArgumentNullException(nameof(selector));
if (sources == null)
throw new ArgumentNullException(nameof(sources));
if (defaultSource == null)
throw new ArgumentNullException(nameof(defaultSource));
return Create<TResult>(observer =>
{
var source = default(IAsyncObservable<TResult>);
try
{
var value = selector();
if (!sources.TryGetValue(value, out source))
{
source = defaultSource;
}
}
catch (Exception ex)
{View on GitHub (pinned to 94b5d5ab91)