{"record":{"id":"4ab49ec1f3833ab2","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-elementselector-groupbyuntil","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'elementSelector')","messagePattern":"Value cannot be null\\. \\(Parameter 'elementSelector'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs","lineNumber":91,"sourceCode":"            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(\n                source,\n                (keySelector, durationSelector, capacity, comparer),\n                static (source, state, observer) => GroupByUntilCore<TSource, TKey, TSource, TDuration>(source, observer, (o, d) => AsyncObserver.GroupByUntil(o, d, state.keySelector, state.durationSelector, state.capacity, state.comparer)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedAsyncObservable<TKey, TElement>, IAsyncObservable<TDuration>> durationSelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n            if (durationSelector == null)\n                throw new ArgumentNullException(nameof(durationSelector));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TElement>>.From(\n                source,\n                (keySelector, elementSelector, durationSelector),\n                static (source, state, observer) => GroupByUntilCore<TSource, TKey, TElement, TDuration>(source, observer, (o, d) => AsyncObserver.GroupByUntil(o, d, state.keySelector, state.elementSelector, state.durationSelector)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedAsyncObservable<TKey, TElement>, IAsyncObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n            if (durationSelector == null)","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs#L73-L109","documentation":"GroupByUntil was called with a null elementSelector Func<TSource, TElement>. The element selector projects each item into its group's element type, and the public factory rejects null for it via ArgumentNullException.","triggerScenarios":"source.GroupByUntil(keySelector, null, durationSelector) — the middle projection argument is null while keySelector and durationSelector are provided.","commonSituations":"Migrating from the 2-selector-free overload and inserting null as a placeholder, a delegate factory returning null, or conditional element projection left unset.","solutions":["Pass an identity projection: x => x.","Provide the actual element projection lambda.","If no element projection is needed, use the overload without elementSelector.","Initialize the delegate field that supplies the selector."],"exampleFix":"// before\nsource.GroupByUntil(x => x.Key, null, g => g.Close());\n// after\nsource.GroupByUntil(x => x.Key, x => x.Value, g => g.Close());","handlingStrategy":"validation","validationCode":"if (elementSelector == null) elementSelector = x => x; // identity projection\nsource.GroupByUntil(keySelector, elementSelector, durationSelector);","typeGuard":"static bool HasElementSelector<TSource,TElem>(Func<TSource,TElem>? f) => f is not null;","tryCatchPattern":"try { grouped = src.GroupByUntil(ks, es, ds); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"elementSelector\") { grouped = src.GroupByUntil(ks, ds); }","preventionTips":["Use x => x explicitly when no projection is needed instead of null.","Prefer the overload without elementSelector when projection is unnecessary.","Keep selector registrations complete in delegate registries.","Enable nullable function types so null placeholders fail at compile time."],"tags":["null-argument","elementselector","groupbyuntil","asyncrx"],"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"}