{"record":{"id":"46b8127038e47518","repo":"dotnet/reactive","slug":"new-argumentnullexception-nameof-scheduler","errorCode":null,"errorMessage":"new ArgumentNullException(nameof(scheduler))","messagePattern":"new ArgumentNullException\\(nameof\\(scheduler\\)\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Generate.cs","lineNumber":358,"sourceCode":"                throw new ArgumentNullException(nameof(timeSelector));\n\n            return Generate(observer, initialState, condition, iterate, resultSelector, timeSelector, TaskPoolAsyncScheduler.Default);\n        }\n\n        public static ValueTask<IAsyncDisposable> Generate<TState, TResult>(IAsyncObserver<TResult> observer, TState initialState, Func<TState, ValueTask<bool>> condition, Func<TState, ValueTask<TState>> iterate, Func<TState, ValueTask<TResult>> resultSelector, Func<TState, ValueTask<TimeSpan>> timeSelector, IAsyncScheduler scheduler)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (condition == null)\n                throw new ArgumentNullException(nameof(condition));\n            if (iterate == null)\n                throw new ArgumentNullException(nameof(iterate));\n            if (resultSelector == null)\n                throw new ArgumentNullException(nameof(resultSelector));\n            if (timeSelector == null)\n                throw new ArgumentNullException(nameof(timeSelector));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return scheduler.ScheduleAsync(async ct =>\n            {\n                var first = true;\n                var state = initialState;\n\n                while (!ct.IsCancellationRequested)\n                {\n                    var hasResult = false;\n                    var result = default(TResult);\n                    var nextDue = default(TimeSpan);\n\n                    try\n                    {\n                        if (first)\n                        {\n                            first = false;\n                        }","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Generate.cs#L340-L376","documentation":"The fully-async Generate overload throws ArgumentNullException when the IAsyncScheduler is null. The scheduler drives ScheduleAsync, iteration delays, and rendezvous continuation; the operator delegates all work to it immediately, so a null scheduler is rejected before any scheduling happens.","triggerScenarios":"Calling Generate(observer, initialState, condition, iterate, resultSelector, timeSelector, scheduler) (Generate.cs:345) with null for the IAsyncScheduler parameter.","commonSituations":"A scheduler resolved from DI/configuration that was never registered; passing null to rely on a default that this overload does not have (only the overloads without a scheduler parameter default to TaskPoolAsyncScheduler.Default).","solutions":["Pass an explicit scheduler such as TaskPoolAsyncScheduler.Default.","Or call the overload without the scheduler parameter, which defaults to TaskPoolAsyncScheduler.Default (see Generate.cs:342, 428).","Fix the scheduler factory/DI registration so it yields a non-null IAsyncScheduler."],"exampleFix":"// before\nGenerate(observer, 0, cond, iter, sel, timeSel, null); // throws\n// after\nGenerate(observer, 0, cond, iter, sel, timeSel, TaskPoolAsyncScheduler.Default);","handlingStrategy":"validation","validationCode":"if (scheduler == null) scheduler = TaskPoolAsyncScheduler.Default;","typeGuard":"static bool HasScheduler(IAsyncScheduler s) => s is not null;","tryCatchPattern":"try { await Generate(observer, state, cond, iter, sel, timeSel, sched); } catch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\") { /* retry with TaskPoolAsyncScheduler.Default */ }","preventionTips":["Default to TaskPoolAsyncScheduler.Default explicitly instead of passing a possibly-null scheduler.","Validate scheduler registrations at application startup, not at query composition time.","Or use the overload without a scheduler parameter to get the default."],"tags":["argument-null","generate","scheduler","async-rx"],"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"}