{"record":{"id":"4a0456c725b58c8e","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-throttledurationselector","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'throttleDurationSelector')","messagePattern":"Value cannot be null\\. \\(Parameter 'throttleDurationSelector'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs","lineNumber":1521,"sourceCode":"        /// <returns>The throttled sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"throttleDurationSelector\"/> is null.</exception>\n        /// <remarks>\n        /// This operator throttles the source sequence by holding on to each element for the duration denoted by <paramref name=\"throttleDurationSelector\"/>.\n        /// 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\n        /// whole process. For streams where the duration computed by applying the <paramref name=\"throttleDurationSelector\"/> to each element overlaps with\n        /// the occurrence of the successor element, the resulting stream won't produce any elements. In order to reduce the volume of a stream whilst\n        /// guaranteeing the periodic production of elements, consider using the Observable.Sample set of operators.\n        /// </remarks>\n        public static IObservable<TSource> Throttle<TSource, TThrottle>(this IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleDurationSelector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (throttleDurationSelector == null)\n            {\n                throw new ArgumentNullException(nameof(throttleDurationSelector));\n            }\n\n            return s_impl.Throttle(source, throttleDurationSelector);\n        }\n\n        #endregion\n\n        #region + TimeInterval +\n\n        /// <summary>\n        /// Records the time interval between consecutive elements in an observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence to record time intervals for.</param>\n        /// <returns>An observable sequence with time interval information on elements.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> is null.</exception>\n        public static IObservable<TimeInterval<TSource>> TimeInterval<TSource>(this IObservable<TSource> source)\n        {","sourceCodeStart":1503,"sourceCodeEnd":1539,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs#L1503-L1539","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide a valid selector lambda, e.g. x => Observable.Timer(TimeSpan.FromMilliseconds(x.ThrottleMs)).","Coalesce or throw a domain-specific error before calling when the selector is optional.","Fix the factory/field supplying the delegate so it is assigned before use."],"exampleFix":"// before\nFunc<Order, IObservable<long>> selector = null; // not wired up yet\nvar t = orders.Throttle(selector); // throws\n// after\nvar t = orders.Throttle(o => Observable.Timer(TimeSpan.FromMilliseconds(o.ThrottleMs)));","handlingStrategy":"validation","validationCode":"if (throttleDurationSelector is null) throw new InvalidOperationException(\"A throttle duration selector must be provided\");\n// or use a sensible default:\nthrottleDurationSelector ??= _ => Observable.Timer(TimeSpan.FromSeconds(1));","typeGuard":"static bool IsValidSelector<TSource,TThrottle>(Func<TSource, IObservable<TThrottle>> sel) => sel is not null;","tryCatchPattern":"try { return source.Throttle(selector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"throttleDurationSelector\") { return source.Throttle(_ => Observable.Timer(TimeSpan.FromSeconds(1))); }","preventionTips":["Avoid optional Func parameters that are forwarded to Rx operators","Initialize selector fields at construction; don't rely on late wiring","Check plugin/reflection-loaded delegates for null before building pipelines"],"tags":["reactive","null-argument","throttle"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}