{"record":{"id":"93e780d1679d5d80","repo":"dotnet/reactive","slug":"accept-should-have-called-only-one-iobserver-t-method","errorCode":null,"errorMessage":"Accept should have called only one IObserver<T> method","messagePattern":"Accept should have called only one IObserver<T> method","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/NotificationAsyncExtensions.cs","lineNumber":58,"sourceCode":"            {\n                _asyncObserver = asyncObserver;\n            }\n\n            public async ValueTask Wait()\n            {\n                if (!_valueTask.HasValue)\n                {\n                    throw new InvalidOperationException(\"Accept did not call any IObserver<T> method\");\n                }\n\n                await _valueTask.Value.ConfigureAwait(false);\n            }\n\n            public void OnCompleted()\n            {\n                if (_valueTask.HasValue)\n                {\n                    throw new InvalidOperationException(\"Accept should have called only one IObserver<T> method\");\n                }\n\n                _valueTask = _asyncObserver.OnCompletedAsync();\n            }\n\n            public void OnError(Exception error)\n            {\n                if (_valueTask.HasValue)\n                {\n                    throw new InvalidOperationException(\"Accept should have called only one IObserver<T> method\");\n                }\n\n                _valueTask = _asyncObserver.OnErrorAsync(error);\n            }\n\n            public void OnNext(T value)\n            {\n                if (_valueTask.HasValue)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/NotificationAsyncExtensions.cs#L40-L76","documentation":"The same visitor in NotificationAsyncExtensions sets _valueTask when one of its IObserver<T> methods runs; if a second callback arrives (here OnCompleted after something already set _valueTask), it throws InvalidOperationException('Accept should have called only one IObserver<T> method'). The IObserver contract for Accept allows exactly one notification dispatch, so multiple calls indicate a malformed notification.","triggerScenarios":"Accepting an INotification<T> whose Accept (or visitor forwarding) invokes more than one observer method — e.g. OnNext followed by OnCompleted, or OnError called twice — from a custom or third-party notification implementation.","commonSituations":"Buggy custom notification types; double-dispatch in wrappers around AcceptAsync; test doubles that replay multiple events through one notification.","solutions":["Ensure the notification calls exactly one IObserver<T> method per Accept.","Use Notification<T>.CreateOnNext/OnError/OnCompleted instead of custom implementations.","Remove wrapper code that forwards Accept to more than one observer callback.","Fix test mocks to model one event per notification."],"exampleFix":"// before (custom notification dispatching twice)\npublic void Accept(IObserver<T> observer) { observer.OnNext(_v); observer.OnCompleted(); }\n// after\npublic void Accept(IObserver<T> observer) => observer.OnNext(_v);","handlingStrategy":"try-catch","validationCode":"if (notification is not Notification<T>) throw new InvalidOperationException(\"Only library-provided Notification<T> instances are supported by AcceptAsync\");","typeGuard":"static bool IsStandardNotification<T>(INotification<T> n) => n is Notification<T>;","tryCatchPattern":"try { await notification.AcceptAsync(asyncObserver); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"only one IObserver<T> method\")) { /* multi-dispatch bug in notification — fix implementation */ }","preventionTips":["One notification == one observer callback, always","Never forward Accept to multiple observer methods in wrappers","Use standard Notification<T>.Create* factories","Review custom INotification types against the visitor contract"],"tags":["invalidoperation","notification","accept","invariant"],"backgroundTag":"internal-invariant-violation","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"}