dotnet/reactive · error · ArgumentNullException
Thrown when observer is null (ArgumentNullException, param…
Error message
Thrown when observer is null (ArgumentNullException, param name: observer)
What it means
The Do(source, observer) overload requires a non-null IObserver<TSource> and throws ArgumentNullException with parameter name 'observer'. The observer's OnNext, OnError, and OnCompleted methods are captured and invoked during enumeration, so null is rejected eagerly at the call site.
Solutions
- Supply a real IObserver implementation or a test double before calling Do
- Default to a no-op observer: `observer ??= NullObserver<T>.Instance;` (or an anonymous implementation)
- Fix the DI/registry wiring that yields a null observer
- Guard the stage: only add Do(observer) when observer != null
Example fix
// before var result = source.Do(null); // after var result = source.Do(new AnonymousObserver<T>(x => Log(x))); // or observer ??= new NopObserver<T>(); var result = source.Do(observer);
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new InvalidOperationException("Observer must be registered before composing Do.");
// or default:
// if (observer is null) observer = new NopObserver<T>(); Type guard
static bool HasObserver<T>(IObserver<T>? o) => o is not null;
Try / catch
try { var result = source.Do(observer!); ... }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { Log("observer missing; attaching no-op observer"); result = source; } Prevention
- Register observers in DI so resolution never returns null
- Provide a shared NopObserver<T>/AnonymousObserver<T> default
- Check HasObserver before composing the Do stage
- Use the callback-based overloads if you only have lambdas, not an IObserver
When it happens
Trigger: `source.Do(null)`; an observer resolved from DI or a registry that returned null; a field/property of observer type never assigned before pipeline construction.
Common situations: Observer registrations missing in the DI container; test doubles (mock observers) not initialized; conditional observer attachment where the observer is null in some environments.
Related errors
- Thrown when source is null (ArgumentNullException, param…
- Value cannot be null. (Parameter 'onCompleted')
- Value cannot be null. (Parameter 'onError')
- Thrown when onCompleted is null (ArgumentNullException…
- Thrown when source is null (ArgumentNullException, param…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/14c41dc7552db006.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs:104
if (onCompleted == null)
throw new ArgumentNullException(nameof(onCompleted));
return DoCore(source, onNext, onError, onCompleted);
}
/// <summary>
/// Lazily invokes observer methods for each value in the sequence, and upon successful or exceptional termination.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="observer">Observer to invoke notification calls on.</param>
/// <returns>Sequence exhibiting the side-effects of observer method invocation upon enumeration.</returns>
public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return DoCore(source, observer.OnNext, observer.OnError, observer.OnCompleted);
}
private static IEnumerable<TSource> DoCore<TSource>(IEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
{
using var e = source.GetEnumerator();
while (true)
{
TSource current;
try
{
if (!e.MoveNext())
break;
current = e.Current;
}View on GitHub (pinned to 94b5d5ab91)