dotnet/reactive · error · ArgumentNullException
source
Error message
source
What it means
Distinct throws ArgumentNullException when the source IAsyncObservable<TSource> is null. The operator filters duplicate elements using a HashSet-backed observer and validates its source eagerly at composition time. Null source is a caller bug, not a recoverable condition.
Solutions
- Ensure a non-null observable is passed to Distinct.
- Fix the upstream producer that returned null instead of an observable.
- Coalesce to AsyncObservable.Empty<TSource>() when null is an expected 'no data' case.
Example fix
// before var distinct = AsyncObservable.Distinct(source); // source == null // after var distinct = source != null ? AsyncObservable.Distinct(source) : AsyncObservable.Empty<int>();
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new InvalidOperationException("Distinct requires a non-null source");
var distinct = AsyncObservable.Distinct(source); Type guard
bool IsValidSource<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try
{
var distinct = AsyncObservable.Distinct(source);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source")
{
logger.LogError(ex, "Distinct called with null source");
throw;
} Prevention
- Treat null observables as bugs; return Empty<TSource>() from producers.
- Use NRT and non-nullable return types on pipeline factories.
- Avoid storing observables in nullable fields without initialization.
When it happens
Trigger: Calling AsyncObservable.Distinct(null) or invoking the extension method on a null reference (static form shown here takes source explicitly).
Common situations: Static invocation Distinct(source) where source comes from a nullable lookup; merging pipelines where one branch produced null.
Related errors
- source
- comparer
- Value cannot be null. (Parameter 'first')
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'subscribeAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7e3a51ec6f507308.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs:14
// 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;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer)));
}
public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source, IEqualityComparer<TSource> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return Create(
source,
comparer,
static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer, comparer)));
}
}
View on GitHub (pinned to 94b5d5ab91)