dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'subscription')
Error message
Value cannot be null. (Parameter 'subscription')
What it means
AsyncObserver.GroupBy requires the IAsyncDisposable representing the upstream subscription so groups can be disposed when the pipeline terminates; a null subscription is rejected with ArgumentNullException. This guard sits in the simplest observer-level overload (observer, subscription, keySelector).
Solutions
- Pass the subscription IAsyncDisposable supplied by the CreateAsyncObservable callback.
- If no disposal is needed, provide a no-op disposable (e.g. AsyncDisposable.Nop / DefaultAsyncDisposable) rather than null.
- Add a null guard with a clear message in the custom operator before delegating.
Example fix
// before return AsyncObserver.GroupBy(observer, null, keySelector); // after return AsyncObserver.GroupBy(observer, subscription ?? AsyncDisposable.Nop, keySelector);
Defensive patterns
Strategy: validation
Validate before calling
subscription ??= AsyncDisposable.Nop; var (o, d) = AsyncObserver.GroupBy(observer, subscription, keySelector);
Type guard
bool HasSubscription(IAsyncDisposable? s) => s is not null;
Try / catch
try
{
var (o, d) = AsyncObserver.GroupBy(observer, subscription, keySelector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "subscription")
{
var (o, d) = AsyncObserver.GroupBy(observer, AsyncDisposable.Nop, keySelector);
} Prevention
- Always propagate the disposable returned alongside the observer from operator callbacks.
- Pair observer and subscription in a single record/struct so they travel together.
- Never dispose-and-null the subscription before passing it to the factory.
When it happens
Trigger: Calling AsyncObserver.GroupBy(observer, subscription, keySelector) with subscription == null, typically when wiring the observer tuple manually.
Common situations: Custom operator code forgets to thread the subscription disposable through; a helper caches the observer but not the subscription; refactor dropped the subscription argument.
Related errors
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'source')
- Value cannot be null.
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/aa49babf7d1740b2.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs:290
var d = new SingleAssignmentAsyncDisposable();
var (sink, subscription) = createObserver(observer, d);
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) GroupBy<TSource, TKey>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, TKey> keySelector)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (subscription == null)
throw new ArgumentNullException(nameof(subscription));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return GroupBy(observer, subscription, keySelector, int.MaxValue, EqualityComparer<TKey>.Default);
}
public static (IAsyncObserver<TSource>, IAsyncDisposable) GroupBy<TSource, TKey>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, TKey> keySelector, 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 (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return GroupBy(observer, subscription, keySelector, int.MaxValue, comparer);View on GitHub (pinned to 94b5d5ab91)