dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'observer')
Error message
Value cannot be null. (Parameter 'observer')
What it means
AsyncObserver.Max<TSource>(IAsyncObserver<TSource>) throws ArgumentNullException('observer') when the downstream observer is null. This factory builds the observer-side Max logic and delegates to Max(observer, Comparer<T>.Default); a null destination observer would have nowhere to emit the result, so it is rejected immediately.
Solutions
- Pass a real downstream observer, e.g. from AsyncObserver.Create<T>(onNextAsync, onErrorAsync, onCompletedAsync).
- In custom operators, validate the observer before forwarding it into AsyncObserver.Max.
- If you want a no-op destination, use a terminal observer (e.g. a TaskCompletionSource-backed observer) instead of null.
Example fix
// before
var maxObserver = AsyncObserver.Max(observer); // observer null
// after
var downstream = AsyncObserver.Create<int>(
x => default(ValueTask),
err => default(ValueTask),
() => default(ValueTask));
var maxObserver = AsyncObserver.Max(downstream); Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new InvalidOperationException("Max requires a downstream observer"); Type guard
static bool HasObserver<TSource>(IAsyncObserver<TSource>? o) => o is not null;
Try / catch
try { var maxObs = AsyncObserver.Max(observer); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* build a terminal observer and retry */ } Prevention
- In custom operators, always forward the incoming observer parameter, never a nullable copy
- Create test observers with AsyncObserver.Create<T> instead of stubbing null
- Add Debug.Assert(observer != null) in operator plumbing during development
When it happens
Trigger: Calling AsyncObserver.Max(null) — commonly when hand-writing an operator and forwarding an observer parameter that is itself null, or when a custom IAsyncObservable.SubscribeAsync implementation passes null through.
Common situations: Custom operator authoring where the Create/subscription plumbing drops the observer; test harnesses that pass null observers; observer factories (e.g. from another operator) returning null on error paths.
Related errors
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'comparer')
- observer
- Value cannot be null. (Parameter 'observer')
- ArgumentNullException(nameof(observer))
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/f11b32f9d6a2966e.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Max.cs:39
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return CreateAsyncObservable<TSource>.From(
source,
comparer,
static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Max(observer, comparer)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Max<TSource>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return Max(observer, Comparer<TSource>.Default);
}
public static IAsyncObserver<TSource> Max<TSource>(IAsyncObserver<TSource> observer, IComparer<TSource> comparer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
var max = default(TSource);
var found = false;
return Create<TSource>(
async x =>
{
if (found)View on GitHub (pinned to 94b5d5ab91)