{"record":{"id":"e875431c6fadd214","repo":"dotnet/reactive","slug":"thrown-when-oncompleted-is-null-argumentnullexception-param","errorCode":null,"errorMessage":"Thrown when onCompleted is null (ArgumentNullException, param name: onCompleted)","messagePattern":"Thrown when onCompleted is null \\(ArgumentNullException, param name: onCompleted\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs","lineNumber":87,"sourceCode":"        /// Lazily invokes an action for each value in the sequence, and executes an action upon successful or exceptional\n        /// 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        /// <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<Exception> onError, 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 (onError == null)\n                throw new ArgumentNullException(nameof(onError));\n            if (onCompleted == null)\n                throw new ArgumentNullException(nameof(onCompleted));\n\n            return DoCore(source, onNext, onError, onCompleted);\n        }\n\n        /// <summary>\n        /// Lazily invokes observer methods for each value in the sequence, and upon successful or exceptional termination.\n        /// </summary>\n        /// <typeparam name=\"TSource\">Source sequence element type.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"observer\">Observer to invoke notification calls on.</param>\n        /// <returns>Sequence exhibiting the side-effects of observer method invocation upon enumeration.</returns>\n        public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs#L69-L105","documentation":"The three-callback Do overload requires a non-null onCompleted action and throws ArgumentNullException with parameter name 'onCompleted'. onCompleted runs on successful termination of the sequence; the library rejects null eagerly so the mistake is caught at the call site, not during enumeration.","triggerScenarios":"`source.Do(x => Log(x), e => Log(e), null)`; a completion callback omitted because it seemed optional; a variable assigned only in some code path.","commonSituations":"Teardown/dispose logic left unwired; pipelines where completion handling was added later but the argument was stubbed null; optional callbacks from configuration.","solutions":["Pass a no-op `() => { }` for onCompleted","Use the Do(source, onNext, onError) overload, which supplies an internal no-op completion handler","Default it: `onCompleted ??= () => { };` before the call","Implement completion handling via other operators (e.g. a Finally-style construct) if that fits better"],"exampleFix":"// before\nvar result = source.Do(x => Log(x), e => Log(e), null);\n// after\nvar result = source.Do(x => Log(x), e => Log(e), () => { });","handlingStrategy":"validation","validationCode":"if (onCompleted is null) onCompleted = static () => { };","typeGuard":"static Action NonNullCompleted(Action? h) => h ?? (static () => { });","tryCatchPattern":"try { var result = source.Do(x => Log(x), e => Log(e), onCompleted!); ... }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onCompleted\") { Log(\"onCompleted callback missing; using no-op\"); }","preventionTips":["Pass () => { } when completion handling is unnecessary","Use the 2-callback Do(source, onNext, onError) overload which defaults onCompleted internally","Keep completion logic inline or default assigned","Enable nullable reference types to surface unassigned callback variables"],"tags":["argumentnull","linq","dotnet","completion-callback"],"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"}