dotnet/wpf · error · InvalidOperationException
throw new…
Error message
throw new InvalidOperationException(SR.Format(SR.SpecialMethodMustBePublic, methodInfo.Name));
What it means
DependencyObjectPropertyDescriptor looks up ShouldSerialize*/ClearValue 'special methods' for a dependency property. If a matching method exists but is not public, it throws InvalidOperationException, because non-public special methods are deliberately unsupported (unlike the CLR TypeDescriptor, which does honor them).
Solutions
- Make the ShouldSerialize/ClearValue method public.
- Rename the method so it no longer matches the special-method naming pattern if it should not be used.
- Remove the method and rely on the dependency property's default serialization behavior.
Example fix
// before internal bool ShouldSerializeWidth() => false; // after public bool ShouldSerializeWidth() => false;
Defensive patterns
Strategy: validation
Validate before calling
var m = type.GetMethod("ShouldSerialize" + propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
if (m != null && !m.IsPublic)
throw new InvalidOperationException($"{m.Name} must be public."); Try / catch
try
{
descriptor.ResetValue(component);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("must be public"))
{
// fix accessibility or skip reset
} Prevention
- Declare ShouldSerialize*/ClearValue helpers as public.
- Remember WPF's DependencyObjectPropertyDescriptor is stricter than CLR TypeDescriptor regarding accessibility.
- Add a unit test that reflects over special methods and asserts IsPublic.
When it happens
Trigger: Declaring a non-public (internal/protected/private) ShouldSerialize<Property> or ClearValue helper method whose name matches a dependency property, then using the property through PropertyDescriptor APIs (e.g. PropertyGrid, serialization, ResetValue).
Common situations: Developers porting classic CLR property patterns (TypeDescriptor picks up non-public ShouldSerialize) to WPF dependency properties; refactoring that reduced method accessibility from public to internal.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Animation_Invalid_DefaultValue
- Cannot remove signature from read-only file.
- Image_EncoderNoColorContext
- Image_EncoderNoGlobalMetadata
- Image_EncoderNoGlobalThumbnail
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3fe4e461e593ace5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/ComponentModel/DependencyObjectPropertyDescriptor.cs:634
}
string methodName = string.Concat(methodPrefix, _dp.Name);
// According to spec, ShouldSerialize and Reset can be non-public. So we should
// assert ReflectionPermission here, like TypeDescriptor does. But since every
// assert is a security risk, we'll take the compatibility hit, and leave it out.
MethodInfo methodInfo = reflectionType.GetMethod(methodName, flags, _dpBinder, types, null);
if (methodInfo != null)
{
// We don't support non-public ShouldSerialize/ClearValue methods. We could just look
// for public methods in the first place, but then authors might get confused as
// to why their non-public method didn't get found, especially because the CLR
// TypeDescriptor does find and use non-public methods.
if( !methodInfo.IsPublic )
{
throw new InvalidOperationException(SR.Format(SR.SpecialMethodMustBePublic, methodInfo.Name));
}
}
return methodInfo;
}
/// <summary>
/// This method is called on demand when we need to get at one or
/// more attributes for this property. Because obtaining attributes
/// can be costly, we wait until now to do the job.
/// </summary>
private void MergeAttributes()
{
AttributeCollection baseAttributes;
if (_property != null)
{
baseAttributes = _property.Attributes;View on GitHub (pinned to 81131a70a4)