{"record":{"id":"0095d10d20c0698c","repo":"dotnet/reactive","slug":"the-observer-has-already-terminated","errorCode":null,"errorMessage":"The observer has already terminated.","messagePattern":"The observer has already terminated\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObserverBase.cs","lineNumber":78,"sourceCode":"            }\n            finally\n            {\n                Interlocked.Exchange(ref _status, Idle);\n            }\n        }\n\n        protected abstract ValueTask OnNextAsyncCore(T value);\n\n        private void TryEnter()\n        {\n            var old = Interlocked.CompareExchange(ref _status, Busy, Idle);\n\n            switch (old)\n            {\n                case Busy:\n                    throw new InvalidOperationException(\"The observer is currently processing a notification.\");\n                case Done:\n                    throw new InvalidOperationException(\"The observer has already terminated.\");\n            }\n        }\n    }\n}\n","sourceCodeStart":60,"sourceCodeEnd":83,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/AsyncObserverBase.cs#L60-L83","documentation":"TryEnter is a serialization guard on the observer's status: it uses Interlocked.CompareExchange to ensure only one notification is processed at a time. This message fires when the status is Done, i.e. OnErrorAsync or OnCompletedAsync was already called and the observer is terminated — any further OnNextAsync/OnErrorAsync/OnCompletedAsync is illegal. Fix: stop issuing notifications after termination, or create a fresh observer.","triggerScenarios":"Thrown at AsyncRx.NET/System.Reactive.Async/AsyncObserverBase.cs:78 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Stop emitting from the source once OnCompleted/OnError has been signaled (e.g. gate emission with the subscription disposable).","Track termination state in the producer before calling OnNextAsync."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}