AvaloniaUI/Avalonia · error · InvalidOperationException

A member accessor can be subscribed to only once.

Error message

A member accessor can be subscribed to only once.

What it means

PropertyAccessorBase enforces single-subscription semantics: Subscribe stores one listener and calls SubscribeCore. Calling Subscribe again while a listener is already set throws InvalidOperationException. The binding engine normally manages this; encountering it means a double subscription of the same accessor instance.

Source

Thrown at src/Avalonia.Base/Data/Core/Plugins/PropertyAccessorBase.cs:37

        public void Dispose()
        {
            if (_listener != null)
            {
                Unsubscribe();
            }
        }

        /// <inheritdoc/>
        public abstract bool SetValue(object? value, BindingPriority priority);

        /// <inheritdoc/>
        public void Subscribe(Action<object?> listener)
        {
            _ = listener ?? throw new ArgumentNullException(nameof(listener));

            if (_listener != null)
            {
                throw new InvalidOperationException(
                    "A member accessor can be subscribed to only once.");
            }

            _listener = listener;
            SubscribeCore();
        }

        public void Unsubscribe()
        {
            if (_listener == null)
            {
                throw new InvalidOperationException(
                    "The member accessor was not subscribed.");
            }

            UnsubscribeCore();
            _listener = null;
        }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Call Unsubscribe (or Dispose) before subscribing again.
  2. Create a fresh accessor instance for each additional listener rather than reusing one.
  3. Let the binding engine own Subscribe/Unsubscribe; do not subscribe manually.

Example fix

// before
accessor.Subscribe(handler1);
accessor.Subscribe(handler2); // throws
// after
accessor.Dispose();
accessor = factory.Create();
accessor.Subscribe(handler2);
Defensive patterns

Strategy: validation

Validate before calling

// Track subscription state and only subscribe once per accessor:
if (_subscribed) { accessor.Dispose(); accessor = CreateAccessor(); }
accessor.Subscribe(handler);
_subscribed = true;

Try / catch

try { accessor.Subscribe(handler); }
catch (InvalidOperationException) { /* dispose and recreate the accessor, then retry */ }

Prevention

When it happens

Trigger: Calling accessor.Subscribe(handler) twice without an intervening Unsubscribe; a custom binding or expression node that subscribes the same accessor twice; sharing one accessor between two consumers.

Common situations: Custom IPropertyAccessor consumers; reusing an accessor across two bindings; forgetting to Dispose/Unsubscribe before re-subscribing.

Related errors


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