{"record":{"id":"c9dbb64493a5a6e7","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-oncompleted-do","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onCompleted')","messagePattern":"Value cannot be null\\. \\(Parameter 'onCompleted'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs","lineNumber":43,"sourceCode":"            return DoCore(source, onNext, _ => { }, () => { });\n        }\n\n        /// <summary>\n        /// Lazily invokes an action for each value in the sequence, and executes an action for successful termination.\n        /// </summary>\n        /// <typeparam name=\"TSource\">Source sequence element type.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"onNext\">Action to invoke for each element.</param>\n        /// <param name=\"onCompleted\">Action to invoke on successful termination of the sequence.</param>\n        /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>\n        public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> 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 DoCore(source, onNext, _ => { }, onCompleted);\n        }\n\n        /// <summary>\n        /// Lazily invokes an action for each value in the sequence, and executes an action upon exceptional termination.\n        /// </summary>\n        /// <typeparam name=\"TSource\">Source sequence element type.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"onNext\">Action to invoke for each element.</param>\n        /// <param name=\"onError\">Action to invoke on exceptional termination of the sequence.</param>\n        /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>\n        public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> 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));","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs#L25-L61","documentation":"The Do operator eagerly validates all arguments before returning the lazily-evaluated wrapped sequence. Passing null for the onCompleted action is rejected immediately with ArgumentNullException so the failure surfaces at the call site instead of during enumeration. The library requires every notification callback to be non-null, even ones that would otherwise do nothing.","triggerScenarios":"Calling Do<TSource>(source, onNext, onCompleted) with a null onCompleted action, e.g. `xs.Do(x => Console.WriteLine(x), null)` or passing a variable that was never assigned.","commonSituations":"Conditional callback assignment where only onError is populated; refactoring from the 2-argument overload to the 3-argument overload and forgetting the completion callback; deserializing callbacks from configuration where an optional handler resolves to null.","solutions":["Pass a no-op action `() => { }` for onCompleted if you do not need completion notification","Use the Do(source, onNext) single-callback overload instead, which supplies the completion handler internally","Ensure the callback variable is assigned before calling Do; guard with `?? new Action(() => { })`","Check for null before the call: `if (onCompleted == null) onCompleted = () => {};`"],"exampleFix":"// before\nvar result = source.Do(x => Log(x), null);\n// after\nvar result = source.Do(x => Log(x), () => { });","handlingStrategy":"validation","validationCode":"if (source is null) throw new ArgumentNullException(nameof(source));\nif (onNext is null) throw new ArgumentNullException(nameof(onNext));\nif (onCompleted is null) onCompleted = () => { };","typeGuard":"static bool IsValidDoArgs<TSource>(IEnumerable<TSource>? s, Action<T>? onCompleted) => s is not null && onCompleted is not null;","tryCatchPattern":"try { var result = source.Do(x => Log(x), onCompleted!); ... }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onCompleted\") { Log(\"onCompleted callback missing; using no-op\"); }","preventionTips":["Pass () => { } for callbacks you do not need rather than null","Prefer the smaller Do overloads that supply internal no-op handlers","Enable nullable reference types so null callbacks are caught at compile time","Validate delegate arguments before composing LINQ pipelines"],"tags":["argumentnull","linq","dotnet","eager-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"}