AvaloniaUI/Avalonia · error · InvalidOperationException

Metadata is already set for {Name} on {type}.

Error message

Metadata is already set for {Name} on {type}.

What it means

Thrown by AvaloniaProperty.OverrideMetadata when metadata has already been registered for the given type. Each type may override a property's metadata exactly once; a second override attempt for the same type is rejected to keep metadata merging deterministic.

Source

Thrown at src/Avalonia.Base/AvaloniaProperty.cs:640

        /// <param name="priority">The priority.</param>
        internal abstract IDisposable RouteBind(
            AvaloniaObject o,
            IObservable<object?> source,
            BindingPriority priority);

        /// <summary>
        /// Overrides the metadata for the property on the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="metadata">The metadata.</param>
        private protected void OverrideMetadata(Type type, AvaloniaPropertyMetadata metadata)
        {
            _ = type ?? throw new ArgumentNullException(nameof(type));
            _ = metadata ?? throw new ArgumentNullException(nameof(metadata));

            if (_metadata.ContainsKey(type))
            {
                throw new InvalidOperationException(
                    $"Metadata is already set for {Name} on {type}.");
            }

            var baseMetadata = GetMetadata(type);
            metadata.Merge(baseMetadata, this);
            metadata.Freeze();
            _metadata.Add(type, metadata);
            _metadataCache.Clear();

            _singleMetadata = null;
            _singleHostType = null;
        }

        private protected abstract IObservable<AvaloniaPropertyChangedEventArgs> GetChanged();

        [MethodImpl(MethodImplOptions.NoInlining)]
        private AvaloniaPropertyMetadata GetMetadataFromCache(AvaloniaObject obj)
        {

View on GitHub (pinned to 11c5427268)

Solutions

  1. Override metadata for each distinct type only once.
  2. Move shared overrides to a single base type and let inheritance propagate.
  3. If loading optional modules, guard the override with a ContainsKey check or a static flag.

Example fix

// before
MyProperty.OverrideMetadata(typeof(MyControl), meta1);
MyProperty.OverrideMetadata(typeof(MyControl), meta2); // throws

// after
MyProperty.OverrideMetadata(typeof(MyControl), meta1);
// do not override the same type again; use a different type or skip
Defensive patterns

Strategy: validation

Validate before calling

if (!AlreadyOverridden(prop, typeof(T)))
    prop.OverrideMetadata(typeof(T), metadata);

static bool AlreadyOverridden(AvaloniaProperty p, Type t) =>
    /* inspect internal cache via a guarded reflection or track a static set */ false;

Try / catch

try { prop.OverrideMetadata(type, metadata); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already set"))
{ /* metadata already overridden; skip */ }

Prevention

When it happens

Trigger: Calling OverrideMetadata(type, metadata) twice for the same type; two modules/assemblies both overriding metadata for the same property on the same type during static init.

Common situations: Class hierarchies where a base and derived both override; test harness re-initializing properties; assembly load order changes causing duplicate overrides.

Related errors


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