dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'throttleDurationSelector')

Error message

Value cannot be null. (Parameter 'throttleDurationSelector')

What it means

Throttle(source, throttleDurationSelector) throws ArgumentNullException when the throttleDurationSelector function is null. The selector supplies per-element throttle durations as inner observables; without it the operator cannot compute windows, so it is validated eagerly.

Solutions

  1. Provide a valid selector lambda, e.g. x => Observable.Timer(TimeSpan.FromMilliseconds(x.ThrottleMs)).
  2. Coalesce or throw a domain-specific error before calling when the selector is optional.
  3. Fix the factory/field supplying the delegate so it is assigned before use.

Example fix

// before
Func<Order, IObservable<long>> selector = null; // not wired up yet
var t = orders.Throttle(selector); // throws
// after
var t = orders.Throttle(o => Observable.Timer(TimeSpan.FromMilliseconds(o.ThrottleMs)));
Defensive patterns

Strategy: validation

Validate before calling

if (throttleDurationSelector is null) throw new InvalidOperationException("A throttle duration selector must be provided");
// or use a sensible default:
throttleDurationSelector ??= _ => Observable.Timer(TimeSpan.FromSeconds(1));

Type guard

static bool IsValidSelector<TSource,TThrottle>(Func<TSource, IObservable<TThrottle>> sel) => sel is not null;

Try / catch

try { return source.Throttle(selector); }
catch (ArgumentNullException ex) when (ex.ParamName == "throttleDurationSelector") { return source.Throttle(_ => Observable.Timer(TimeSpan.FromSeconds(1))); }

Prevention

When it happens

Trigger: Calling source.Throttle((Func<MyItem, IObservable<TimeSpan>>)null) or passing a selector field/property that was never assigned; reflection-built delegate caches returning null on first call.

Common situations: Optional selector parameters defaulted to null then forwarded; late-bound plugin systems where the selector assembly failed to load; typos in property names when wiring delegates via reflection.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:1521

        /// <returns>The throttled sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="throttleDurationSelector"/> is null.</exception>
        /// <remarks>
        /// This operator throttles the source sequence by holding on to each element for the duration denoted by <paramref name="throttleDurationSelector"/>.
        /// If another element is produced within this time window, the element is dropped and a new timer is started for the current element, repeating this
        /// whole process. For streams where the duration computed by applying the <paramref name="throttleDurationSelector"/> to each element overlaps with
        /// the occurrence of the successor element, the resulting stream won't produce any elements. In order to reduce the volume of a stream whilst
        /// guaranteeing the periodic production of elements, consider using the Observable.Sample set of operators.
        /// </remarks>
        public static IObservable<TSource> Throttle<TSource, TThrottle>(this IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleDurationSelector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (throttleDurationSelector == null)
            {
                throw new ArgumentNullException(nameof(throttleDurationSelector));
            }

            return s_impl.Throttle(source, throttleDurationSelector);
        }

        #endregion

        #region + TimeInterval +

        /// <summary>
        /// Records the time interval between consecutive elements in an observable sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to record time intervals for.</param>
        /// <returns>An observable sequence with time interval information on elements.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IObservable<TimeInterval<TSource>> TimeInterval<TSource>(this IObservable<TSource> source)
        {

View on GitHub (pinned to 94b5d5ab91)