{"record":{"id":"958307dea7f092b8","repo":"dotnet/reactive","slug":"throw-new-argumentnullexception-nameof-scheduler-958307","errorCode":null,"errorMessage":"throw new ArgumentNullException(nameof(scheduler))","messagePattern":"throw new ArgumentNullException\\(nameof\\(scheduler\\)\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs","lineNumber":1057,"sourceCode":"        /// <summary>\n        /// Expands an observable sequence by recursively invoking selector, using the specified scheduler to enumerate the queue of obtained sequences.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence and each of the recursively expanded sources obtained by running the selector function.</typeparam>\n        /// <param name=\"source\">Source sequence with the initial elements.</param>\n        /// <param name=\"selector\">Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.</param>\n        /// <param name=\"scheduler\">Scheduler on which to perform the expansion by enumerating the internal queue of obtained sequences.</param>\n        /// <returns>An observable sequence containing all the elements produced by the recursive expansion.</returns>\n        /// <exception cref=\"ArgumentNullException\">\n        /// <paramref name=\"source\" /> or <paramref name=\"selector\" /> or <paramref name=\"scheduler\" /> is null.</exception>\n        [Experimental]\n        public static IQbservable<TSource> Expand<TSource>(this IQbservable<TSource> source, Expression<Func<TSource, IObservable<TSource>>> selector, IScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return source.Provider.CreateQuery<TSource>(\n                Expression.Call(\n                    null,\n                    new Func<IQbservable<TSource>, Expression<Func<TSource, IObservable<TSource>>>, IScheduler, IQbservable<TSource>>(Expand<TSource>).Method,\n                    source.Expression,\n                    selector,\n                    Expression.Constant(scheduler, typeof(IScheduler))\n                )\n            );\n        }\n#endif\n\n#if !STABLE\n        /// <summary>\n        /// Runs all specified observable sequences in parallel and collects their last elements.\n        /// </summary>\n        /// <param name=\"provider\">Query provider used to construct the <see cref=\"IQbservable{T}\"/> data source.</param>","sourceCodeStart":1039,"sourceCodeEnd":1075,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs#L1039-L1075","documentation":"The scheduler overload Expand(source, selector, scheduler) requires an IScheduler to time recursive expansions; a null scheduler throws ArgumentNullException named 'scheduler'. Rx requires an explicit scheduler here because Expand's recursion depends on scheduling semantics that cannot be defaulted inside a queryable expression tree.","triggerScenarios":"Calling source.Expand(selector, null) — scheduler from a null configuration value, a TestScheduler variable not yet created, or an IScheduler dependency that failed to resolve.","commonSituations":"DI failing to provide IScheduler; config where the scheduler name wasn't mapped; passing null deliberately in unit tests to mean 'default' instead of using Scheduler.Default.","solutions":["Pass a concrete scheduler such as Scheduler.Default, Scheduler.CurrentThread, or Scheduler.Immediate","Resolve IScheduler from DI and assert non-null before composing the query","Provide an overload without a scheduler if scheduling is genuinely optional"],"exampleFix":"// before\nsource.Expand(x => Observable.Return(x), scheduler); // scheduler is null\n// after\nvar scheduler = configuredScheduler ?? Scheduler.Default;\nsource.Expand(x => Observable.Return(x), scheduler);","handlingStrategy":"validation","validationCode":"if (scheduler == null)\n    throw new InvalidOperationException(\"Expand requires an IScheduler; use Scheduler.Default\");","typeGuard":"bool HasScheduler(IScheduler s) => s is not null;","tryCatchPattern":"try\n{\n    var query = source.Expand(x => Observable.Return(x), scheduler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\")\n{\n    logger.LogError(ex, \"Expand scheduler was null\");\n}","preventionTips":["Coalesce configured schedulers with Scheduler.Default at pipeline setup","Register IScheduler in DI and validate at startup","Never pass null to mean 'default' — use the no-scheduler overload instead"],"tags":["argumentnull","rx","expand","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-23T08:17:48.524Z"}