{"record":{"id":"f9ef6ff963d20b0e","repo":"dotnet/reactive","slug":"throw-new-argumentnullexception-nameof-scheduler-observable","errorCode":null,"errorMessage":"throw new ArgumentNullException(nameof(scheduler));","messagePattern":"throw new ArgumentNullException\\(nameof\\(scheduler\\)\\);","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs","lineNumber":246,"sourceCode":"        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (timeSpan < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(timeSpan));\n            }\n\n            if (count <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(count));\n            }\n\n            if (scheduler == null)\n            {\n                throw new ArgumentNullException(nameof(scheduler));\n            }\n\n            return s_impl.Buffer(source, timeSpan, count, scheduler);\n        }\n\n        #endregion\n\n        #endregion\n\n        #region + Delay +\n\n        #region TimeSpan\n\n        /// <summary>\n        /// Time shifts the observable sequence by the specified relative time duration.\n        /// The relative time intervals between the values are preserved.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs#L228-L264","documentation":"The Buffer(source, timeSpan, count, scheduler) overload throws ArgumentNullException when the IScheduler is null. The scheduler drives the timed closure of buffers, so it is mandatory in this overload. Rx validates this eagerly to fail at the call site rather than at subscription time.","triggerScenarios":"Calling Observable.Buffer(source, timeSpan, count, null) — typically a null scheduler from an uninitialized field, an unregistered DI service, or a helper that conditionally passes a scheduler.","commonSituations":"IScheduler not registered in the DI container; test scaffolding that meant to inject TestScheduler but left it null; optional scheduler parameters forwarded as null.","solutions":["Pass Scheduler.Default, Scheduler.ThreadPool, Scheduler.TaskPool, or a TestScheduler in tests","Register IScheduler in the DI container and verify resolution succeeds","Use the non-scheduler overload Buffer(source, timeSpan, count) to get the default scheduler"],"exampleFix":"// before\nIScheduler sched = container.Resolve<IScheduler>(); // may return null\nvar buffered = source.Buffer(TimeSpan.FromSeconds(1), 5, sched);\n// after\nvar buffered = source.Buffer(TimeSpan.FromSeconds(1), 5, Scheduler.Default);","handlingStrategy":"validation","validationCode":"if (scheduler is null) throw new ArgumentNullException(nameof(scheduler));\n// or: scheduler ??= Scheduler.Default;","typeGuard":"static bool HasScheduler(IScheduler? s) => s is not null;","tryCatchPattern":"try { var b = source.Buffer(timeSpan, count, scheduler); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\") { scheduler = Scheduler.Default; /* retry */ }","preventionTips":["Use Scheduler.Default when no specific scheduler is required","Register IScheduler in DI and verify at startup","Use TestScheduler explicitly in tests instead of null placeholders"],"tags":["rx","argument-validation","null-argument","scheduler"],"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"}