{"record":{"id":"fd67bbd0372052d2","repo":"dotnet/reactive","slug":"argumentnullexception-nameof-witness","errorCode":null,"errorMessage":"ArgumentNullException(nameof(witness))","messagePattern":"ArgumentNullException\\(nameof\\(witness\\)\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Do.cs","lineNumber":157,"sourceCode":"                throw new ArgumentNullException(nameof(onError));\n            if (onCompleted == null)\n                throw new ArgumentNullException(nameof(onCompleted));\n\n            return Create(\n                source,\n                (onNext, onError, onCompleted),\n                static (source, state, target) => source.SubscribeSafeAsync(AsyncObserver.Do(target, state.onNext, state.onError, state.onCompleted)));\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<TSource> Do<TSource>(IAsyncObserver<TSource> observer, IAsyncObserver<TSource> witness)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (witness == null)\n                throw new ArgumentNullException(nameof(witness));\n\n            return Create<TSource>(\n                async x =>\n                {\n                    try\n                    {\n                        await witness.OnNextAsync(x).ConfigureAwait(false);\n                    }\n                    catch (Exception ex)\n                    {\n                        await observer.OnErrorAsync(ex).ConfigureAwait(false);\n                        return;\n                    }\n\n                    await observer.OnNextAsync(x).ConfigureAwait(false);\n                },\n                async error =>\n                {","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Do.cs#L139-L175","documentation":"The Do(observer, witness) overload throws ArgumentNullException when the witness argument is null. In this operator the witness is a second observer that receives a copy of every notification for side effects (logging, tracing); the library validates it up front because a null witness would crash the first time the source emits a notification. The primary observer and the witness are independently required.","triggerScenarios":"Calling AsyncObserver.Do<TSource>(validObserver, null) — a non-null observer but a null IAsyncObserver<TSource> witness.","commonSituations":"The witness (often a logging/tracing observer) is resolved lazily and is null because a logger was not configured; a conditional tracing observer is only built in some branches but Do is called unconditionally; a typo passes the wrong variable that is null.","solutions":["Pass a real witness observer; if no side effect is desired, drop the witness overload and use Do(observer) or pass AsyncObserver.Create<TSource>(_ => default, _ => default, () => default) as a no-op witness.","Verify that the factory/DI path producing the witness (e.g. a tracing observer built from a logger) cannot return null.","If the witness is optional in your design, guard with `witness ?? noopWitness` before composing."],"exampleFix":"// before\nvar obs = AsyncObserver.Do<int>(downstream, traceObserver); // traceObserver null when tracing disabled\n\n// after\nvar noopWitness = AsyncObserver.Create<int>(_ => default, _ => default, () => default);\nvar obs = AsyncObserver.Do<int>(downstream, traceObserver ?? noopWitness);","handlingStrategy":"validation","validationCode":"if (witness is null)\n    witness = AsyncObserver.Create<T>(_ => default, _ => default, () => default); // no-op witness\nvar result = AsyncObserver.Do(source, observer, witness);","typeGuard":"static bool IsUsableWitness<T>(IAsyncObserver<T>? w) => w is not null;","tryCatchPattern":"try\n{\n    var obs = AsyncObserver.Do(source, observer, witness);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"witness\")\n{\n    log.LogWarning(\"tracing witness missing; falling back to plain Do\");\n    obs = AsyncObserver.Do(source, observer);\n}","preventionTips":["Default optional witnesses to a no-op observer rather than null","Verify logger/tracing initialization before building tracing observers","Only call the witness overload when tracing is actually enabled","Use nullable reference types to catch unassigned witness variables"],"tags":["null-argument","argument-validation","async-reactive"],"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"}