dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'subscription')

Error message

Value cannot be null. (Parameter 'subscription')

What it means

The capacity-based GroupByUntil overload requires an IAsyncDisposable subscription used to tie the operator's lifetime to the outer subscription. It throws ArgumentNullException when subscription is null.

Solutions

  1. Pass the subscription disposable supplied by the enclosing query composition (e.g. from Create/Subscribe plumbing).
  2. Create a disposable (e.g. AsyncDisposable or a composite of upstream disposables) to represent the subscription.
  3. Guard with a null check and skip calling the operator when no subscription exists.
Defensive patterns

Strategy: validation

Validate before calling

if (subscription == null) throw new InvalidOperationException("GroupByUntil requires a subscription disposable");

Type guard

static bool HasSubscription(IAsyncDisposable d) => d is not null;

Try / catch

try { await GroupByUntil(observer, subscription, keySel, durSel, capacity); } catch (ArgumentNullException ex) when (ex.ParamName == "subscription") { /* create a disposable and retry */ }

Prevention

When it happens

Trigger: Calling GroupByUntil(observer, subscription, keySelector, durationSelector, capacity) with a null IAsyncDisposable subscription argument.

Common situations: Directly invoking internal operator entry points from custom query composition or tests without creating a subscription disposable first.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/ceb248608dc41255. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs:490

                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 (comparer == null)
                throw new ArgumentNullException(nameof(comparer));

            return GroupByUntil(observer, subscription, keySelector, durationSelector, int.MaxValue, comparer);
        }

        public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> GroupByUntil<TSource, TKey, TDuration>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, ValueTask<TKey>> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity)
        {
            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, ValueTask<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));

View on GitHub (pinned to 94b5d5ab91)