dotnet/wpf · error · NotSupportedException

SR.CantSetReadonlyProperty

Error message

SR.CantSetReadonlyProperty

What it means

XamlMemberInvoker.SetValue writes the member's value via its underlying setter. When the member has no setter (read-only property), NotSupportedException with SR.CantSetReadonlyProperty (formatted with the member) is thrown since there is no setter to invoke.

Solutions

  1. Check `invoker.UnderlyingSetter is null` (or member.IsWritePublic / CanWrite) before calling SetValue.
  2. For read-only collection properties, get the instance via GetValue and call Add on it rather than SetValue.
  3. Add a setter to the target property if writing is truly required.

Example fix

// before
member.Invoker.SetValue(obj, newList); // NotSupportedException on read-only property
// after
if (member.Invoker.UnderlyingSetter is not null)
    member.Invoker.SetValue(obj, newList);
else if (member.Invoker.GetValue(obj) is IList list)
{
    list.Clear();
    foreach (var item in (IEnumerable)newList) list.Add(item);
}
Defensive patterns

Strategy: type-guard

Validate before calling

bool canWrite = member.Invoker.UnderlyingSetter is not null;

Type guard

static bool CanWrite(XamlMember m) => m.Invoker.UnderlyingSetter is not null;

Try / catch

try { invoker.SetValue(instance, value); }
catch (NotSupportedException) { /* read-only member: use GetValue + mutation or skip */ }

Prevention

When it happens

Trigger: Calling invoker.SetValue(instance, value) where the XamlMember wraps a read-only property (getter only, UnderlyingSetter is null), e.g. `invoker.SetValue(obj, val)` on a collection-returning or computed property.

Common situations: XAML object-writer/property-injection code applying values generically; settings copies via reflection where read-only collections (e.g. Keys, Dimensions) are targeted; deserializers not honoring read-only members.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ec25a56bdb695139. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Schema/XamlMemberInvoker.cs:76

            }

            if (UnderlyingGetter.IsStatic)
            {
                return UnderlyingGetter.Invoke(null, new object[] { instance });
            }
            else
            {
                return UnderlyingGetter.Invoke(instance, Array.Empty<object>());
            }
        }

        public virtual void SetValue(object instance, object value)
        {
            ArgumentNullException.ThrowIfNull(instance);
            ThrowIfUnknown();
            if (UnderlyingSetter is null)
            {
                throw new NotSupportedException(SR.Format(SR.CantSetReadonlyProperty, _member));
            }

            if (UnderlyingSetter.IsStatic)
            {
                UnderlyingSetter.Invoke(null, new object[] { instance, value });
            }
            else
            {
                UnderlyingSetter.Invoke(instance, new object[] { value });
            }
        }

        internal static XamlMemberInvoker DirectiveInvoker
        {
            get
            {
                if (s_Directive is null)
                {

View on GitHub (pinned to 81131a70a4)