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
- Check `invoker.UnderlyingSetter is null` (or member.IsWritePublic / CanWrite) before calling SetValue.
- For read-only collection properties, get the instance via GetValue and call Add on it rather than SetValue.
- 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
- Check CanWrite/UnderlyingSetter before generic SetValue calls
- Mutate read-only collections in place (GetValue then Add)
- Design DTOs consumed by XAML writers with setters where population is expected
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
- SR.CantGetWriteonlyProperty
- SR.MustNotCallSetter
- SR.NotSupportedOnDirective
- SR.NotSupportedOnUnknownMember
- SR.OnlySupportedOnCollections
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)