dotnet/reactive · error · ArgumentNullException
ArgumentNullException (default message: Value cannot be…
Error message
ArgumentNullException (default message: Value cannot be null. (Parameter 'comparer'))
What it means
The Distinct(source, comparer) overload requires both arguments non-null; this throw site is the comparer == null check that runs after source validation. The comparer is needed to build the internal deduplication set, so the library rejects null eagerly.
Solutions
- Pass a valid comparer instance, e.g., EqualityComparer<TSource>.Default for default semantics
- Fix the factory/DI registration that was supposed to supply the comparer
- If default equality is acceptable, use the comparer-less Distinct() overload instead
- Add a null check on the comparer at construction time
Example fix
// before IEqualityComparer<string> cmp = _comparerProvider?.Get(); // may be null var result = source.Distinct(cmp); // after var result = source.Distinct(cmp ?? EqualityComparer<string>.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (comparer is null) throw new ArgumentNullException(nameof(comparer)); // or: comparer ??= EqualityComparer<TSource>.Default;
Type guard
bool HasComparer<TSource>(IEqualityComparer<TSource>? comparer) => comparer is not null;
Try / catch
try { var result = source.Distinct(comparer); }
catch (ArgumentNullException ex) when (ex.ParamName == "comparer")
{
result = source.Distinct(); // fall back to default equality
} Prevention
- Pass EqualityComparer<T>.Default instead of null when default semantics are fine
- Check that comparer-providing services are registered in DI before use
- Assign comparer variables at declaration, never leave them conditionally unset
- Prefer the comparer-less Distinct() overload when a custom comparer is optional
When it happens
Trigger: Calling Distinct<TSource>(source, null) — a valid source but a null IEqualityComparer<TSource>.
Common situations: A comparer resolved from configuration/DI was not registered, or a custom comparer variable was never assigned before building the query.
Related errors
- ArgumentNullException (default message: Value cannot be…
- ArgumentNullException (default message: Value cannot be…
- comparer
- comparer (Parameter 'comparer')
- first
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/67433c66a3188a24.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs:113
/// <summary>
/// Returns an observable sequence that contains only distinct elements according to the comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">An observable sequence to retain distinct elements for.</param>
/// <param name="comparer">Equality comparer for source elements.</param>
/// <returns>An observable sequence only containing the distinct elements from the source sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
/// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
public static IObservable<TSource> Distinct<TSource>(this IObservable<TSource> source, IEqualityComparer<TSource> comparer)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (comparer == null)
{
throw new ArgumentNullException(nameof(comparer));
}
return s_impl.Distinct(source, comparer);
}
/// <summary>
/// Returns an observable sequence that contains only distinct elements according to the keySelector.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TKey">The type of the discriminator key computed for each element in the source sequence.</typeparam>
/// <param name="source">An observable sequence to retain distinct elements for.</param>
/// <param name="keySelector">A function to compute the comparison key for each element.</param>
/// <returns>An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
/// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
public static IObservable<TSource> Distinct<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
{
if (source == null)View on GitHub (pinned to 94b5d5ab91)