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

  1. Dispose the first subscription before subscribing again.
  2. Use a multicasting observable (Subject / the framework's standard observable) if you need multiple subscribers.
  3. 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

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


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/9eff4da6337c7b3e. Report an issue: GitHub.