{"record":{"id":"c52cd048ecbeaf5e","repo":"dotnet/reactive","slug":"throw-new-argumentnullexception-nameof-delaydurationselector","errorCode":null,"errorMessage":"throw new ArgumentNullException(nameof(delayDurationSelector));","messagePattern":"throw new ArgumentNullException\\(nameof\\(delayDurationSelector\\)\\);","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs","lineNumber":437,"sourceCode":"        /// <summary>\n        /// Time shifts the observable sequence based on a delay selector function for each element.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <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>\n        /// <param name=\"source\">Source sequence to delay values for.</param>\n        /// <param name=\"delayDurationSelector\">Selector function to retrieve a sequence indicating the delay for each given element.</param>\n        /// <returns>Time-shifted sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"delayDurationSelector\"/> is null.</exception>\n        public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delayDurationSelector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (delayDurationSelector == null)\n            {\n                throw new ArgumentNullException(nameof(delayDurationSelector));\n            }\n\n            return s_impl.Delay(source, delayDurationSelector);\n        }\n\n        /// <summary>\n        /// Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <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>\n        /// <param name=\"source\">Source sequence to delay values for.</param>\n        /// <param name=\"subscriptionDelay\">Sequence indicating the delay for the subscription to the source.</param>\n        /// <param name=\"delayDurationSelector\">Selector function to retrieve a sequence indicating the delay for each given element.</param>\n        /// <returns>Time-shifted sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"subscriptionDelay\"/> or <paramref name=\"delayDurationSelector\"/> is null.</exception>\n        public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector)\n        {\n            if (source == null)","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs#L419-L455","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nFunc<Order, IObservable<long>> sel = _config.Selector; // null\nvar delayed = orders.Delay(sel);\n// after\nvar delayed = orders.Delay(o => Observable.Timer(TimeSpan.FromMilliseconds(o.DelayMs)));","handlingStrategy":"validation","validationCode":"if (selector is null) selector = x => Observable.Timer(TimeSpan.FromMilliseconds(x.DelayMs));\nvar delayed = source.Delay(selector);","typeGuard":"static bool HasSelector<TSrc,TDur>(Func<TSrc, IObservable<TDur>>? f) => f is not null;","tryCatchPattern":"try { var delayed = source.Delay(selector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"delayDurationSelector\") { /* supply a default selector */ }","preventionTips":["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"],"tags":["rx","argument-null","delegate","dotnet"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}