dotnet/reactive · error · ArgumentNullException
throw new…
Error message
throw new ArgumentNullException(nameof(delayDurationSelector));
What it means
Delay<TSource,TDelay>(source, delayDurationSelector) requires a non-null selector function that maps each element to a duration observable. A null selector makes the operator unable to compute any delays, so it throws ArgumentNullException eagerly.
Solutions
- Pass a concrete selector lambda, e.g. x => Observable.Timer(TimeSpan.FromMilliseconds(x.Delay)).
- Fix the injection/assignment so the selector Func is populated before use.
- If the delay should be constant, use the Delay(source, TimeSpan) overload instead of a selector.
- Guard: if (selector == null) throw new InvalidOperationException(...) with context, or provide a default selector.
Example fix
// before Func<Order, IObservable<long>> sel = _config.Selector; // null var delayed = orders.Delay(sel); // after var delayed = orders.Delay(o => Observable.Timer(TimeSpan.FromMilliseconds(o.DelayMs)));
Defensive patterns
Strategy: validation
Validate before calling
if (selector is null) selector = x => Observable.Timer(TimeSpan.FromMilliseconds(x.DelayMs)); var delayed = source.Delay(selector);
Type guard
static bool HasSelector<TSrc,TDur>(Func<TSrc, IObservable<TDur>>? f) => f is not null;
Try / catch
try { var delayed = source.Delay(selector); }
catch (ArgumentNullException ex) when (ex.ParamName == "delayDurationSelector") { /* supply a default selector */ } Prevention
- Provide default selectors in configurable pipelines
- Validate injected Func dependencies at startup
- Use the timespan-based Delay overload for constant delays
- Avoid reflection-driven delegate construction that can yield null
When it happens
Trigger: Calling Observable.Delay(source, null), or passing a selector variable that is null (a Func field never assigned, a lambda conditional that resolved to null, a strategy object returning a null Func).
Common situations: Configurable pipelines where the selector is injected and the injection failed; reflection-based code passing null delegates; forgetting the lambda when converting from the timespan-based Delay overload.
Related errors
- nameof(subscribe)
- Value cannot be null. (Parameter 'source9')
- ArgumentNullException(nameof(resultSelector))
- Value cannot be null. (Parameter 'selector')
- Value cannot be null. (Parameter 'collectionSelector')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/c52cd048ecbeaf5e.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:437
/// <summary>
/// Time shifts the observable sequence based on a delay selector function for each element.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TDelay">The type of the elements in the delay sequences used to denote the delay duration of each element in the source sequence.</typeparam>
/// <param name="source">Source sequence to delay values for.</param>
/// <param name="delayDurationSelector">Selector function to retrieve a sequence indicating the delay for each given element.</param>
/// <returns>Time-shifted sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="delayDurationSelector"/> is null.</exception>
public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delayDurationSelector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (delayDurationSelector == null)
{
throw new ArgumentNullException(nameof(delayDurationSelector));
}
return s_impl.Delay(source, delayDurationSelector);
}
/// <summary>
/// Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TDelay">The type of the elements in the delay sequences used to denote the delay duration of each element in the source sequence.</typeparam>
/// <param name="source">Source sequence to delay values for.</param>
/// <param name="subscriptionDelay">Sequence indicating the delay for the subscription to the source.</param>
/// <param name="delayDurationSelector">Selector function to retrieve a sequence indicating the delay for each given element.</param>
/// <returns>Time-shifted sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="subscriptionDelay"/> or <paramref name="delayDurationSelector"/> is null.</exception>
public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector)
{
if (source == null)View on GitHub (pinned to 94b5d5ab91)