{"record":{"id":"a98863ff54f8f4ca","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-onerror","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onError')","messagePattern":"Value cannot be null\\. \\(Parameter 'onError'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObservableExtensions.cs","lineNumber":77,"sourceCode":"\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Action<T> onNext)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (onNext == null)\n                throw new ArgumentNullException(nameof(onNext));\n\n            return source.SubscribeAsync(new AsyncObserver<T>(x => { onNext(x); return default; }, ex => new ValueTask(Task.FromException(ex)), () => default));\n        }\n\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Action<T> onNext, Action<Exception> onError)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (onNext == null)\n                throw new ArgumentNullException(nameof(onNext));\n            if (onError == null)\n                throw new ArgumentNullException(nameof(onError));\n\n            return source.SubscribeAsync(new AsyncObserver<T>(x => { onNext(x); return default; }, ex => { onError(ex); return default; }, () => default));\n        }\n\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Action<T> onNext, Action onCompleted)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (onNext == null)\n                throw new ArgumentNullException(nameof(onNext));\n            if (onCompleted == null)\n                throw new ArgumentNullException(nameof(onCompleted));\n\n            return source.SubscribeAsync(new AsyncObserver<T>(x => { onNext(x); return default; }, ex => new ValueTask(Task.FromException(ex)), () => { onCompleted(); return default; }));\n        }\n\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted)\n        {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/AsyncObservableExtensions.cs#L59-L95","documentation":"Thrown by the two-action SubscribeAsync(source, onNext, onError) overload when the onError action is null. The library requires a non-null error handler so faults on the source do not become unhandled exceptions, and throws ArgumentNullException at subscribe time.","triggerScenarios":"Calling SubscribeAsync(source, onNext, null), e.g. omitting error handling because the caller expects exceptions to propagate via the ValueTask await.","commonSituations":"Migration from callbacks APIs without error handlers, or code where the error logger is injected and can be null in tests.","solutions":["Pass a real error handler such as ex => Log(ex) or ex => { } if truly ignoring.","Use the SubscribeAsync(source, onNext) overload, which installs a default error handler that faults the subscription.","Ensure injected dependencies used as error handlers are non-null before subscribing."],"exampleFix":"// before\nawait source.SubscribeAsync(x => Render(x), null);\n// after\nawait source.SubscribeAsync(x => Render(x), ex => Console.Error.WriteLine(ex));","handlingStrategy":"validation","validationCode":"if (onError == null) throw new ArgumentNullException(nameof(onError));\nawait source.SubscribeAsync(onNext, onError);","typeGuard":"bool HasErrorHandler(Action<Exception> onError) => onError is not null;","tryCatchPattern":"try\n{\n    await source.SubscribeAsync(onNext, onError);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onError\")\n{\n    await source.SubscribeAsync(onNext, ex => Console.Error.WriteLine(ex));\n}","preventionTips":["Always supply an error action; use the source+onNext overload to get a default faulting handler.","Wire a logging fallback in shared subscription helpers so onError is never null.","Ensure injected loggers/handlers are non-null in test and production compositions.","Review subscription sites for all handler arguments before merging."],"tags":["csharp","null-argument","asyncrx","argument-validation"],"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"}