{"record":{"id":"19c9e27d94e1a118","repo":"dotnet/reactive","slug":"nameof-scheduler-observable-concurrency","errorCode":null,"errorMessage":"nameof(scheduler)","messagePattern":"nameof\\(scheduler\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Concurrency.cs","lineNumber":35,"sourceCode":"        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"scheduler\">Scheduler to notify observers on.</param>\n        /// <returns>The source sequence whose observations happen on the specified scheduler.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"scheduler\"/> is null.</exception>\n        /// <remarks>\n        /// This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects\n        /// that require to be run on a scheduler, use <see cref=\"Observable.SubscribeOn{TSource}(IObservable{TSource}, IScheduler)\"/>.\n        /// </remarks>\n        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, IScheduler scheduler)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (scheduler == null)\n            {\n                throw new ArgumentNullException(nameof(scheduler));\n            }\n\n            return s_impl.ObserveOn(source, scheduler);\n        }\n\n        /// <summary>\n        /// Wraps the source sequence in order to run its observer callbacks on the specified synchronization context.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"context\">Synchronization context to notify observers on.</param>\n        /// <returns>The source sequence whose observations happen on the specified synchronization context.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"context\"/> is null.</exception>\n        /// <remarks>\n        /// This only invokes observer callbacks on a synchronization context. In case the subscription and/or unsubscription actions have side-effects\n        /// that require to be run on a synchronization context, use <see cref=\"Observable.SubscribeOn{TSource}(IObservable{TSource}, SynchronizationContext)\"/>.\n        /// </remarks>\n        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Concurrency.cs#L17-L53","documentation":"System.ArgumentNullException thrown by Observable.ObserveOn<TSource>(IObservable<TSource>, IScheduler) when the scheduler argument is null. The public wrapper validates both parameters before delegating to s_impl.ObserveOn, so a null IScheduler is rejected up front rather than failing later inside the operator.","triggerScenarios":"Calling source.ObserveOn(scheduler) with scheduler == null, e.g.ObserveOn(Schedulers.Default) typed as a variable that was never assigned, or passing the result of a lookup/factory that returned null.","commonSituations":"Resolving an IScheduler from DI/config where the registration is missing; a scheduler field initialized after first use; refactoring away from scheduler properties (ThreadPool/TaskPool/NewThread) and leaving a null placeholder.","solutions":["Pass a concrete IScheduler, e.g. System.Reactive.Concurrency Scheduler.Default, ThreadPoolScheduler.Instance, or EventLoopScheduler.","Check the variable supplying the scheduler for null before calling ObserveOn and fix its initialization or DI registration.","If the scheduler is optional, guard with 'scheduler ?? Scheduler.Default' instead of passing null."],"exampleFix":"// before\nvar sched = config.Scheduler; // may be null\nsource.ObserveOn(sched);\n// after\nvar sched = config.Scheduler ?? Scheduler.Default;\nsource.ObserveOn(sched);","handlingStrategy":"validation","validationCode":"if (scheduler is null) throw new InvalidOperationException(\"scheduler must be set before calling ObserveOn\");\nsource.ObserveOn(scheduler);","typeGuard":"bool HasScheduler(IScheduler s) => s is not null;","tryCatchPattern":"try { obs = source.ObserveOn(scheduler); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\") { obs = source.ObserveOn(Scheduler.Default); }","preventionTips":["Never pass a scheduler obtained from a nullable lookup without a ?? fallback to Scheduler.Default.","Prefer concrete static schedulers (Scheduler.Default, TaskPoolScheduler.Default) over nullable fields.","Keep IScheduler DI registrations mandatory so resolution fails fast instead of injecting null."],"tags":["null-argument","scheduler","rx","argumentnull"],"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"}