{"record":{"id":"e4439c1e55134bc2","repo":"dotnet/reactive","slug":"subscribescheduler","errorCode":null,"errorMessage":"subscribeScheduler","messagePattern":"subscribeScheduler","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs","lineNumber":27,"sourceCode":"{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> SubscribeOn<TSource>(this IAsyncObservable<TSource> source, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return SubscribeOn(source, scheduler, scheduler);\n        }\n\n        public static IAsyncObservable<TSource> SubscribeOn<TSource>(this IAsyncObservable<TSource> source, IAsyncScheduler subscribeScheduler, IAsyncScheduler disposeScheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (subscribeScheduler == null)\n                throw new ArgumentNullException(nameof(subscribeScheduler));\n            if (disposeScheduler == null)\n                throw new ArgumentNullException(nameof(disposeScheduler));\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                (subscribeScheduler, disposeScheduler),\n                static async (source, state, observer) =>\n                {\n                    var m = new SingleAssignmentAsyncDisposable();\n                    var d = new SerialAsyncDisposable();\n\n                    await d.AssignAsync(m).ConfigureAwait(false);\n\n                    var scheduled = await state.subscribeScheduler.ScheduleAsync(async ct =>\n                    {\n                        var subscription = await source.SubscribeSafeAsync(observer).RendezVous(state.subscribeScheduler, ct);\n\n                        var scheduledDispose = AsyncDisposable.Create(async () =>","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs#L9-L45","documentation":"SubscribeOn(source, subscribeScheduler, disposeScheduler) validates each scheduler. Passing a null subscribeScheduler throws ArgumentNullException(\"subscribeScheduler\") because subscription must be dispatched onto it.","triggerScenarios":"Calling source.SubscribeOn(source, null, disposeScheduler) — typically when the subscribe scheduler was meant to be inferred or was misassigned; also happens when constructing the tuple of schedulers from config where one entry is missing.","commonSituations":"Config only defines a dispose scheduler; a scheduler field initialized asynchronously and read before assignment; copy-paste from the single-scheduler overload leaving one argument null.","solutions":["Pass a concrete subscribe scheduler, or call the single-scheduler overload SubscribeOn(source, scheduler) which uses the same scheduler for both.","Fix the null initialization of the scheduler variable.","Validate both schedulers before calling (see validation pattern)."],"exampleFix":"// before\nvar obs = source.SubscribeOn(null, disposeScheduler);\n// after\nvar obs = source.SubscribeOn(subscribeScheduler ?? AsyncScheduler.DefaultScheduler, disposeScheduler);","handlingStrategy":"validation","validationCode":"if (subscribeScheduler == null)\n    throw new ArgumentNullException(nameof(subscribeScheduler));\nif (disposeScheduler == null)\n    throw new ArgumentNullException(nameof(disposeScheduler));","typeGuard":"bool SchedulersValid(IAsyncScheduler? s, IAsyncScheduler? d) => s is not null && d is not null;","tryCatchPattern":"try\n{\n    var obs = source.SubscribeOn(subscribeScheduler, disposeScheduler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"subscribeScheduler\")\n{\n    logger.LogError(ex, \"Null subscribe scheduler\");\n    obs = source.SubscribeOn(AsyncScheduler.DefaultScheduler, disposeScheduler);\n}","preventionTips":["Default both scheduler parameters at the call site before invoking.","Keep scheduler pairs in a small record/struct validated at construction.","Prefer the single-scheduler overload when both phases share one scheduler."],"tags":["argument-null","scheduler","subscribe-on","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-23T08:17:48.524Z"}