dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'observer')
Error message
Value cannot be null. (Parameter 'observer')
What it means
Thrown by AsyncObserver.Single<TSource>(IAsyncObserver<TSource>) when the downstream observer is null. This is the observer-side factory used internally by the operator but it is public, so direct callers must supply a valid observer. The guard exists to keep the async observer chain well-formed from the start.
Solutions
- Pass a valid IAsyncObserver<TSource> instance
- In custom operators, ensure the observer parameter is validated or propagated from the subscription call
- Use Create(source, ...) operators instead of composing raw AsyncObserver factories
Example fix
// before var obs = AsyncObserver.Single<int>(null); // after var obs = AsyncObserver.Single<int>(myDownstreamObserver);
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer));
Type guard
static bool HasObserver<T>(IAsyncObserver<T>? o) => o is not null;
Try / catch
try { var o = AsyncObserver.Single<T>(observer); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* construct or substitute observer */ } Prevention
- Obtain observers from SubscribeAsync callbacks, never store them in nullable fields
- Validate observer parameters at the top of custom operators
- Favor operator-level APIs over raw AsyncObserver composition
When it happens
Trigger: Calling AsyncObserver.Single(observer) directly with a null observer, typically when composing custom async observer pipelines.
Common situations: Custom operator implementations passing through an uninitialized observer field; test harnesses constructing observers manually.
Related errors
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'error')
- ArgumentNullException
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/327026da3228b994.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Single.cs:55
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
return CreateAsyncObservable<TSource>.From(
source,
predicate,
static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Single(observer, predicate)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Single<TSource>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
var hasValue = false;
var value = default(TSource);
return Create<TSource>(
async x =>
{
if (hasValue)
{
await observer.OnErrorAsync(new InvalidOperationException("The sequence contains more than one element.")).ConfigureAwait(false);
return;
}
hasValue = true;
value = x;
},
observer.OnErrorAsync,
async () =>View on GitHub (pinned to 94b5d5ab91)