dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'observer')
Error message
Value cannot be null. (Parameter 'observer')
What it means
This ArgumentNullException is thrown by the internal static Window<TSource> helper (observer, subscription, count) when the downstream IAsyncObserver<IAsyncObservable<TSource>> is null. This helper implements the count-based Window operator's core; it validates the observer, subscription, count, and skip before wiring up the queue of async subjects. A null observer means the operator has nothing to push window observables to.
Solutions
- Pass a valid IAsyncObserver<IAsyncObservable<TSource>> (e.g. the observer supplied to your operator's SubscribeAsync).
- If calling from a custom operator, forward the observer you received rather than constructing a null.
- In tests, provide a stub/mock observer instead of null.
- Guard your own code with ArgumentNullException.ThrowIfNull before delegating so the failure surfaces at your boundary.
Example fix
// before var (winObs, disp) = WindowOperators.Window<TSource>(null, subscription, 5); // after var (winObs, disp) = WindowOperators.Window<TSource>(observer, subscription, 5);
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer));
Type guard
bool IsValidObserver<TSource>(IAsyncObserver<IAsyncObservable<TSource>>? o) => o is not null;
Try / catch
try
{
var (winObs, disp) = WindowOperators.Window<TSource>(observer, subscription, count);
}
catch (ArgumentNullException ex) when (ex.ParamName == "observer")
{
throw new InvalidOperationException("Window helper requires a downstream observer.", ex);
} Prevention
- Always forward the observer received in SubscribeAsync into operator helpers.
- In tests, use stub observers instead of null placeholders.
- Add ArgumentNullException.ThrowIfNull at the top of custom operators.
When it happens
Trigger: Calling Window(observer, subscription, count) or Window(observer, subscription, count, skip) with a null observer argument — typically from custom operator plumbing or tests that pass null for the observer.
Common situations: Writing a custom async-Rx operator that composes Window's internals; unit tests exercising the helper with placeholder nulls; refactoring that dropped observer creation before the call.
Related errors
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'windowBoundaries')
- Value cannot be null. (Parameter 'windowClosingSelector')
- Value cannot be null. (Parameter 'subscription')
- nameof(finallyAction)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/ed4b2ffdd838f5db.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Window.cs:221
var d = new SingleAssignmentAsyncDisposable();
var (sink, subscription) = await createObserverAsync(observer, d).ConfigureAwait(false);
var inner = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);
await d.AssignAsync(inner).ConfigureAwait(false);
return subscription;
}
}
public partial class AsyncObserver
{
public static (IAsyncObserver<TSource>, IAsyncDisposable) Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, int count) => Window(observer, subscription, count, count);
public static (IAsyncObserver<TSource>, IAsyncDisposable) Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, int count, int skip)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (subscription == null)
throw new ArgumentNullException(nameof(subscription));
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
if (skip <= 0)
throw new ArgumentOutOfRangeException(nameof(skip));
var refCount = new RefCountAsyncDisposable(subscription);
var queue = new Queue<IAsyncSubject<TSource>>();
var n = 0;
return
(
Create<TSource>
(
async x =>
{View on GitHub (pinned to 94b5d5ab91)