{"record":{"id":"de78d0aea1ba4ec6","repo":"dotnet/reactive","slug":"source-subscribeon","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs","lineNumber":15,"sourceCode":"﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System.Reactive.Concurrency;\nusing System.Reactive.Disposables;\n\nnamespace System.Reactive.Linq\n{\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),","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs#L1-L33","documentation":"ArgumentNullException guard in AsyncObservable.SubscribeOn: the source async observable to be subscribed on the given scheduler was null. Since there is no sequence to schedule subscription work for, the operator throws before touching the scheduler.","triggerScenarios":"Calling someObservable.SubscribeOn(scheduler) where the receiver observable is null (e.g. a chain built from a null-returning factory or variable), or calling it as a static-style call SubscribeOn(null, scheduler).","commonSituations":"An observable-producing method returns null on an error path; conditional pipeline construction leaves the source unset; querying an optional configuration for the source.","solutions":["Ensure the observable you call SubscribeOn on is non-null; check the upstream factory/method return value.","Guard with a fallback observable if the source may legitimately be missing.","If the pipeline is optional, skip SubscribeOn entirely when source is null."],"exampleFix":"// before\nvar obs = factory.Create(); // may return null\nvar scheduled = obs.SubscribeOn(scheduler);\n// after\nvar obs = factory.Create() ?? AsyncObservable.Empty<int>();\nvar scheduled = obs.SubscribeOn(scheduler);","handlingStrategy":"validation","validationCode":"if (source == null)\n    throw new InvalidOperationException(\"Source observable must be non-null before SubscribeOn\");","typeGuard":"static bool IsObservable<T>(IAsyncObservable<T>? o) => o is not null;","tryCatchPattern":"try\n{\n    var scheduled = source.SubscribeOn(scheduler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\")\n{\n    logger.LogError(ex, \"Null observable passed to SubscribeOn\");\n    scheduled = AsyncObservable.Empty<TSource>();\n}","preventionTips":["Ensure every observable-producing method throws instead of returning null on failure.","Coalesce with AsyncObservable.Empty<T>() when a source may be absent.","Enable nullable reference type annotations on pipeline variables."],"tags":["argument-null","source","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"}