dotnet/reactive · error · ArgumentNullException
observer
Error message
observer
What it means
AsyncObserver.Distinct throws ArgumentNullException when the downstream IAsyncObserver<TSource> is null. This observer-facing factory is used inside custom operator implementations and delegates to Distinct(observer, EqualityComparer<TSource>.Default). The null check happens before any observer chain is built.
Solutions
- Pass the real downstream observer you received in your subscribe delegate.
- Add your own ArgumentNullException guards at the entry of your custom operator.
- Prefer the built-in Create(source, observer) operator helper over manual observer construction.
Example fix
// before AsyncObserver.Distinct(null); // throws // after return source.SubscribeSafeAsync(AsyncObserver.Distinct(downstreamObserver));
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer)); var distinctObserver = AsyncObserver.Distinct(observer);
Type guard
bool HasDownstream<T>(IAsyncObserver<T>? o) => o is not null;
Try / catch
try
{
var o = AsyncObserver.Distinct(observer);
}
catch (ArgumentNullException ex) when (ex.ParamName == "observer")
{
logger.LogError(ex, "Distinct observer factory got null observer");
throw;
} Prevention
- Never construct observer chains with variables that may be null.
- Guard custom operator entry points before delegating to observer factories.
- Test custom operators' null-argument behavior explicitly.
When it happens
Trigger: Calling AsyncObserver.Distinct(null) from a custom subscribe path or forwarding a null observer argument.
Common situations: Hand-written operators where the observer passed into Create's subscribe delegate is misused or lost; wiring observers across layers where one layer passes null.
Related errors
- observer
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'observer')
- null (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/42817760047ba4a1.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs:38
{
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)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Distinct<TSource>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return Distinct(observer, EqualityComparer<TSource>.Default);
}
public static IAsyncObserver<TSource> Distinct<TSource>(IAsyncObserver<TSource> observer, IEqualityComparer<TSource> comparer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
var set = new HashSet<TSource>(comparer);
return Create<TSource>(
async x =>
{
var added = false;
View on GitHub (pinned to 94b5d5ab91)