{"record":{"id":"9eff4da6337c7b3e","repo":"AvaloniaUI/Avalonia","slug":"the-observable-can-only-be-subscribed-once","errorCode":null,"errorMessage":"The observable can only be subscribed once.","messagePattern":"The observable can only be subscribed once\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs","lineNumber":19,"sourceCode":"﻿using System;\nusing Avalonia.Threading;\n\nnamespace Avalonia.Reactive\n{\n    internal abstract class SingleSubscriberObservableBase<T> : IObservable<T>, IDisposable\n    {\n        private Exception? _error;\n        private IObserver<T>? _observer;\n        private bool _completed;\n\n        public IDisposable Subscribe(IObserver<T> observer)\n        {\n            _ = observer ?? throw new ArgumentNullException(nameof(observer));\n            Dispatcher.UIThread.VerifyAccess();\n\n            if (_observer != null)\n            {\n                throw new InvalidOperationException(\"The observable can only be subscribed once.\");\n            }\n\n            if (_error != null)\n            {\n                observer.OnError(_error);\n            }\n            else if (_completed)\n            {\n                observer.OnCompleted();\n            }\n            else\n            {\n                _observer = observer;\n                Subscribed();\n            }\n\n            return this;\n        }","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs#L1-L37","documentation":"Thrown by SingleSubscriberObservableBase<T>.Subscribe when a second subscriber attempts to attach while the first is still active. This base is deliberately single-subscriber by design (it holds one _observer field and drives one source). It is not a general-purpose multicast observable.","triggerScenarios":"Calling Subscribe twice on the same SingleSubscriberObservableBase instance without disposing the first subscription. Internally this can happen if two bindings bind to the same single-subscriber source concurrently.","commonSituations":"Two controls/styles bind to the same one-shot observable source; a subscription is made, the object is reused, and a second subscription is attempted; the previous subscription's IDisposable was not disposed before resubscribing.","solutions":["Dispose the first subscription before subscribing again.","Use a multicasting observable (Subject / the framework's standard observable) if you need multiple subscribers.","Audit bindings that share a single-subscriber source and give each its own source instance."],"exampleFix":"// before\nvar sub1 = source.Subscribe(o1);\nvar sub2 = source.Subscribe(o2); // throws\n// after\nvar sub1 = source.Subscribe(o1);\nsub1.Dispose();\nvar sub2 = source.Subscribe(o2);","handlingStrategy":"validation","validationCode":"// single-subscriber: dispose previous before re-subscribing\n_prev?.Dispose();\n_prev = source.Subscribe(observer);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track the previous subscription IDisposable and dispose before resubscribing.","If multiple consumers are needed, multicast through a different observable type.","Give each binding its own single-subscriber source rather than sharing."],"tags":["reactive","single-subscriber","invalid-operation","lifecycle","binding"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}