dotnet/reactive · error · ArgumentNullException
ArgumentNullException: observer
Error message
ArgumentNullException: observer
What it means
The full-overload GroupByUntil(observer, subscription, keySelector, durationSelector, capacity, comparer) (GroupByUntil.cs:365) first validates its observer argument — the IAsyncObserver that receives the grouped observables — and throws ArgumentNullException when it is null. Without an observer there is nowhere to deliver group results, so the call is rejected up front.
Solutions
- Supply a valid IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> to the operator
- Check where the observer comes from — ensure the subscription/pipeline was fully initialized before calling GroupByUntil
- If writing a custom operator, throw or defer subscription when the downstream observer is null instead of forwarding it
Example fix
// before
await AsyncObservable.GroupByUntil(null, subscription, k => k, g => g.Take(1), 8, cmp);
// after
if (observer == null) throw new InvalidOperationException("observer not initialized");
await AsyncObservable.GroupByUntil(observer, subscription, k => k, g => g.Take(1), 8, cmp); Defensive patterns
Strategy: validation
Validate before calling
if (observer == null) throw new InvalidOperationException("Downstream observer must be initialized before applying GroupByUntil"); Type guard
bool HasObserver<TSource>(IAsyncObserver<TSource>? o) => o is not null;
Try / catch
try { var res = AsyncObservable.GroupByUntil(observer, subscription, keySelector, durationSelector, capacity, comparer); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* re-create or await the pipeline observer */ } Prevention
- Apply operators only inside a fully constructed subscription pipeline
- Avoid storing downstream observers in nullable fields read lazily
- Cover custom operator composition with integration tests through Subscribe
When it happens
Trigger: Invoking the internal/operator surface of GroupByUntil with observer == null; in practice this happens in custom pipeline code or operator composition where the downstream observer is a nullable field or the result of a failed lookup.
Common situations: Writing custom operators that forward a downstream observer which can be null before subscription completes; unit tests constructing the operator manually; DI containers producing null observer instances.
Related errors
- ArgumentNullException: durationSelector
- ArgumentNullException: comparer
- Argument cannot be null (Parameter name: functionAsync)
- Argument cannot be null (Parameter name: scheduler)
- elementSelector
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/e4531eb96dcf6f89.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs:368
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (subscription == null)
throw new ArgumentNullException(nameof(subscription));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (durationSelector == null)
throw new ArgumentNullException(nameof(durationSelector));
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
return GroupByUntil(observer, subscription, keySelector, durationSelector, capacity, EqualityComparer<TKey>.Default);
}
public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> GroupByUntil<TSource, TKey, TDuration>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, TKey> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity, IEqualityComparer<TKey> comparer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (subscription == null)
throw new ArgumentNullException(nameof(subscription));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (durationSelector == null)
throw new ArgumentNullException(nameof(durationSelector));
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return GroupByUntil(observer, subscription, x => new ValueTask<TKey>(keySelector(x)), durationSelector, capacity, comparer);
}
public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> GroupByUntil<TSource, TKey, TElement, TDuration>(IAsyncObserver<IGroupedAsyncObservable<TKey, TElement>> observer, IAsyncDisposable subscription, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedAsyncObservable<TKey, TElement>, IAsyncObservable<TDuration>> durationSelector)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));View on GitHub (pinned to 94b5d5ab91)