{"record":{"id":"2814f5e3bd93e740","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-observer-groupbyuntil","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'observer')","messagePattern":"Value cannot be null\\. \\(Parameter 'observer'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs","lineNumber":488,"sourceCode":"        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscription == null)\n                throw new ArgumentNullException(nameof(subscription));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (durationSelector == null)\n                throw new ArgumentNullException(nameof(durationSelector));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return GroupByUntil(observer, subscription, keySelector, durationSelector, int.MaxValue, comparer);\n        }\n\n        public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> GroupByUntil<TSource, TKey, TDuration>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, ValueTask<TKey>> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscription == null)\n                throw new ArgumentNullException(nameof(subscription));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (durationSelector == null)\n                throw new ArgumentNullException(nameof(durationSelector));\n            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n\n            return GroupByUntil(observer, subscription, keySelector, durationSelector, capacity, EqualityComparer<TKey>.Default);\n        }\n\n        public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> GroupByUntil<TSource, TKey, TDuration>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, ValueTask<TKey>> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity, IEqualityComparer<TKey> comparer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscription == null)\n                throw new ArgumentNullException(nameof(subscription));","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs#L470-L506","documentation":"The capacity-based GroupByUntil overload (observer, subscription, keySelector, durationSelector, capacity) validates each argument and throws ArgumentNullException when observer is null. The observer is the downstream subscriber the operator must forward grouped sequences to; without it the operator cannot function.","triggerScenarios":"Calling GroupByUntil(observer, subscription, keySelector, durationSelector, capacity) with a null IAsyncObserver<TSource>, typically via a delegate or reflection where the observer argument was not supplied.","commonSituations":"Writing custom query-operator plumbing where the downstream observer variable is null because subscription setup failed, or building operator chains dynamically.","solutions":["Pass the actual downstream observer from your subscription pipeline.","Check the pipeline wiring that produced the observer so it is initialized before calling GroupByUntil.","If you must call the operator directly, obtain the observer from a Create/call-operators helper rather than passing null."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (observer == null) throw new InvalidOperationException(\"GroupByUntil requires a downstream observer\");","typeGuard":"static bool HasObserver<TSource>(IAsyncObserver<TSource> o) => o is not null;","tryCatchPattern":"try { await GroupByUntil(observer, sub, keySel, durSel, capacity); } catch (ArgumentNullException ex) when (ex.ParamName == \"observer\") { /* fix pipeline wiring / log */ }","preventionTips":["Only call operator internals from within a subscription composition that supplies an observer.","Assert non-null observer in custom operator wrappers.","Prefer public query-syntax operators over direct static calls."],"tags":["null-argument","argument-validation","reactive-extensions"],"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"}