AvaloniaUI/Avalonia · error · InvalidOperationException
The observable can only be subscribed once.
Error message
The observable can only be subscribed once.
What it means
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.
Source
Thrown at src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs:19
using System;
using Avalonia.Threading;
namespace Avalonia.Reactive
{
internal abstract class SingleSubscriberObservableBase<T> : IObservable<T>, IDisposable
{
private Exception? _error;
private IObserver<T>? _observer;
private bool _completed;
public IDisposable Subscribe(IObserver<T> observer)
{
_ = observer ?? throw new ArgumentNullException(nameof(observer));
Dispatcher.UIThread.VerifyAccess();
if (_observer != null)
{
throw new InvalidOperationException("The observable can only be subscribed once.");
}
if (_error != null)
{
observer.OnError(_error);
}
else if (_completed)
{
observer.OnCompleted();
}
else
{
_observer = observer;
Subscribed();
}
return this;
}View on GitHub (pinned to 11c5427268)
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.
Example fix
// before var sub1 = source.Subscribe(o1); var sub2 = source.Subscribe(o2); // throws // after var sub1 = source.Subscribe(o1); sub1.Dispose(); var sub2 = source.Subscribe(o2);
Defensive patterns
Strategy: validation
Validate before calling
// single-subscriber: dispose previous before re-subscribing _prev?.Dispose(); _prev = source.Subscribe(observer);
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Object of type '{value?.GetType()}' cannot be converted to t
- A member accessor can be subscribed to only once.
- The member accessor was not subscribed.
- Value cannot be null. (Parameter 'compositeDisposable')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/9eff4da6337c7b3e.
Report an issue: GitHub.