AvaloniaUI/Avalonia · error · InvalidOperationException
The metadata is read-only.
Error message
The metadata is read-only.
What it means
Thrown by AvaloniaPropertyMetadata.Merge when the metadata instance has been frozen (IsReadOnly == true). Avalonia freezes property metadata once the property is fully registered so that shared metadata cannot be mutated after the fact. Calling Merge on already-frozen metadata violates that immutability contract.
Source
Thrown at src/Avalonia.Base/AvaloniaPropertyMetadata.cs:65
public bool? EnableDataValidation { get; private set; }
/// <summary>
/// Gets whether this instance is read-only and can't be modified.
/// </summary>
public bool IsReadOnly { get; private set; }
/// <summary>
/// Merges the metadata with the base metadata.
/// </summary>
/// <param name="baseMetadata">The base metadata to merge.</param>
/// <param name="property">The property to which the metadata is being applied.</param>
public virtual void Merge(
AvaloniaPropertyMetadata baseMetadata,
AvaloniaProperty property)
{
if (IsReadOnly)
{
throw new InvalidOperationException("The metadata is read-only.");
}
if (_defaultBindingMode == BindingMode.Default)
{
_defaultBindingMode = baseMetadata.DefaultBindingMode;
}
EnableDataValidation ??= baseMetadata.EnableDataValidation;
}
/// <summary>
/// Makes this instance read-only.
/// No further modifications are allowed after this call.
/// </summary>
public void Freeze()
=> IsReadOnly = true;
/// <summary>View on GitHub (pinned to 11c5427268)
Solutions
- Ensure Merge/OverrideMetadata is called before the property registration freezes the metadata.
- Call GenerateTypeSafeMetadata() to obtain a fresh, writable copy of the metadata and merge into that instead.
- If you hold a reference to frozen metadata, create a new AvaloniaPropertyMetadata instance with the desired values rather than mutating the frozen one.
- Check metadata.IsReadOnly before calling Merge and skip or copy accordingly.
Example fix
// before (mutates frozen metadata)
property.GetMetadata(ownerType).Merge(baseMetadata, property);
// after (work on a fresh copy)
if (metadata.IsReadOnly) {
var copy = metadata.GenerateTypeSafeMetadata();
copy.Merge(baseMetadata, property);
} Defensive patterns
Strategy: validation
Validate before calling
if (metadata.IsReadOnly) { /* use GenerateTypeSafeMetadata() copy instead */ } Type guard
static bool IsMetadataWritable(AvaloniaPropertyMetadata m) => !m.IsReadOnly;
Prevention
- Always check AvaloniaPropertyMetadata.IsReadOnly before calling Merge.
- Prefer OverrideMetadata at registration time, before the property freezes its metadata.
- Use GenerateTypeSafeMetadata() to obtain a writable copy instead of mutating shared metadata.
When it happens
Trigger: Calling metadata.Merge(baseMetadata, property) on an AvaloniaPropertyMetadata whose Freeze() method has already run (setting IsReadOnly=true). This occurs during OverrideMetadata calls or manual metadata merging after the property registration sequence has frozen the metadata.
Common situations: Overriding styled/direct property metadata at runtime after the property has been sealed; attempting to call OverrideMetadata more than once; sharing a single metadata instance across multiple AvaloniaProperty registrations and then trying to merge into it again.
Related errors
- Metadata is already set for {Name} on {type}.
- Property '{property.Name} not registered on '{o.GetType()}
- Attached properties not supported.
- Cannot register a non-attached property as attached.
- Duration value cannot be negative.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/3e59ccd824156dd9.
Report an issue: GitHub.