dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'observer')
Error message
Value cannot be null. (Parameter 'observer')
What it means
Materialize wraps an observer so that every OnNext/OnError/OnCompleted is surfaced as a Notification<TSource> value. The library eagerly validates that the downstream observer is not null and throws ArgumentNullException with parameter name 'observer' at the top of the factory method, before any subscription happens.
Solutions
- Pass a non-null IAsyncObserver<Notification<TSource>> instance to Materialize
- Check the factory/expression producing the observer for a code path that returns null
- If the observer may legitimately be absent, use AsyncObserver./* no-op */ observer or a stub implementation instead of null
Example fix
// before
var obs = GetObserverOrNull();
var m = AsyncObserver.Materialize<int>(obs); // throws if null
// after
var obs = GetObserverOrNull() ?? AsyncObserver.Create<Notification<int>>(async n => { });
var m = AsyncObserver.Materialize<int>(obs); Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer)); // or guard at call site: System.Diagnostics.Debug.Assert(observer != null, "observer must be non-null before Materialize");
Type guard
static bool IsValidObserver<T>(IAsyncObserver<T> o) => o is not null;
Try / catch
try
{
var materialized = AsyncObserver.Materialize(sourceObserver);
}
catch (ArgumentNullException ex) when (ex.ParamName == "observer")
{
// supply a default observer or surface a configuration error
} Prevention
- Never pass null where an IAsyncObserver is expected; use a no-op observer instead
- Validate delegates/observers at pipeline construction time, not at subscribe time
- Keep observer creation in one factory that never returns null
When it happens
Trigger: Calling AsyncObserver.Materialize<TSource>(null), or passing a variable/chain expression that resolves to null (e.g. a factory method that returned null instead of an observer).
Common situations: Building custom operator pipelines where an observer is produced conditionally; refactoring code so a previously non-null observer field is no longer initialized; calling Materialize before wiring up the pipeline.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/8e7a1f581851495a.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Materialize.cs:23
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<Notification<TSource>> Materialize<TSource>(this IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create<TSource, Notification<TSource>>(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Materialize(observer)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Materialize<TSource>(IAsyncObserver<Notification<TSource>> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return Create<TSource>(
x => observer.OnNextAsync(Notification.CreateOnNext(x)),
async ex =>
{
await observer.OnNextAsync(Notification.CreateOnError<TSource>(ex)).ConfigureAwait(false);
await observer.OnCompletedAsync().ConfigureAwait(false);
},
async () =>
{
await observer.OnNextAsync(Notification.CreateOnCompleted<TSource>()).ConfigureAwait(false);
await observer.OnCompletedAsync().ConfigureAwait(false);
}
);
}
}
}
View on GitHub (pinned to 94b5d5ab91)