{"record":{"id":"863378feb5543f6a","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-selector","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'selector')","messagePattern":"Value cannot be null\\. \\(Parameter 'selector'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Case.cs","lineNumber":20,"sourceCode":"// 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.Collections.Generic;\nusing System.Reactive.Concurrency;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources) => Case(selector, sources, Empty<TResult>());\n\n        public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources, IAsyncScheduler scheduler) => Case(selector, sources, Empty<TResult>(scheduler));\n\n        public static IAsyncObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IAsyncObservable<TResult>> sources, IAsyncObservable<TResult> defaultSource)\n        {\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n            if (sources == null)\n                throw new ArgumentNullException(nameof(sources));\n            if (defaultSource == null)\n                throw new ArgumentNullException(nameof(defaultSource));\n\n            return Create<TResult>(observer =>\n            {\n                var source = default(IAsyncObservable<TResult>);\n\n                try\n                {\n                    var value = selector();\n\n                    if (!sources.TryGetValue(value, out source))\n                    {\n                        source = defaultSource;\n                    }\n                }","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Case.cs#L2-L38","documentation":"Thrown by the Case operator (Case(selector, sources, defaultSource), reached via the scheduler overload too) when the selector function is null. Case calls selector per subscription to pick which source observable from the dictionary to subscribe to; a null selector would crash at subscribe time, so it is validated when the operator is built.","triggerScenarios":"Calling Case<TValue, TResult>(selector, sources, scheduler) or Case(selector, sources, defaultSource) with selector == null, e.g. a delegate resolved from DI/config that is null.","commonSituations":"Key-selector delegates stored in nullable fields; switching logic where the mode function was removed in a refactor; test doubles returning null selectors.","solutions":["Pass a concrete selector, e.g. () => settings.Mode or () => key.","Coalesce with a default key function: selector ?? (() => defaultKey).","Validate the delegate at construction of your pipeline, before composing Case."],"exampleFix":"// before\nvar stream = Case(modeSelector, sources, defaultSource); // modeSelector null\n// after\nvar sel = modeSelector ?? (() => ModeKey.Default);\nvar stream = Case(sel, sources, defaultSource);","handlingStrategy":"validation","validationCode":"if (selector is null) throw new ArgumentNullException(nameof(selector));","typeGuard":"bool HasSelector<TValue>(Func<TValue>? f) => f is not null;","tryCatchPattern":"try { var s = Case(selector, sources, defaultSource); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"selector\") { /* provide selector */ }","preventionTips":["Store key selectors as required (non-nullable) constructor dependencies","Coalesce with a default key function when optional","Resolve DI-injected delegates before composing the observable chain"],"tags":["asyncrx","argumentnull","case","selector"],"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"}