{"record":{"id":"63fc061ed4cf08c5","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-onnext-do","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onNext')","messagePattern":"Value cannot be null\\. \\(Parameter 'onNext'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs","lineNumber":23,"sourceCode":"using System.Collections.Generic;\n\nnamespace System.Linq\n{\n    public static partial class EnumerableEx\n    {\n        /// <summary>\n        /// Lazily invokes an action for each value in the sequence.\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        /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>\n        public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> 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 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));","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs#L5-L41","documentation":"Do(source, onNext) requires a non-null Action<TSource> and throws ArgumentNullException with parameter name 'onNext' when it is null. The onNext delegate is the essence of the operator, so it is validated eagerly at call time. Without this check the failure would only appear as a NullReferenceException on the first enumerated element.","triggerScenarios":"Passing a null Action<TSource> — e.g. an optional observer callback variable never assigned, a conditional expression yielding null, or forwarding a null optional parameter into Do.","commonSituations":"Configurable logging hooks where the action is optional and forwarded raw, event-handler fields not yet wired, dynamic pipelines built from a delegate registry with missing entries.","solutions":["Provide a real action, or pass a no-op: onNext ?? (_ => { }) when the callback is genuinely optional.","If no per-element action is needed, drop the Do operator entirely.","Null-check the delegate at your boundary and throw with context.","Fix the delegate producer (DI registration, registry, config) that returned null."],"exampleFix":"// before\nvar logged = seq.Do(_loggerHook); // _loggerHook null when logging disabled\n// after\nvar logged = _loggerHook != null ? seq.Do(_loggerHook) : seq;","handlingStrategy":"validation","validationCode":"if (onNext is null)\n{\n    // skip Do entirely when there is no per-element action\n}\nelse\n{\n    var result = source.Do(onNext);\n}","typeGuard":"static bool HasAction<T>(Action<T>? a) => a is not null;","tryCatchPattern":"try\n{\n    var result = source.Do(onNext);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onNext\")\n{\n    result = source; // no per-element side effect needed\n}","preventionTips":["Only compose Do when you actually have an action; conditionally apply it","Default optional callbacks to no-ops rather than null","Never pass nullable delegate fields straight into operators","Make hook registrations explicit so missing hooks fail at configuration time"],"tags":["argumentnull","linq","ix-net","null-check"],"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"}