dotnet/wpf · error · XamlObjectReaderException

SR.ObjectReaderInstanceDescriptorInvalidMethod

Error message

SR.ObjectReaderInstanceDescriptorInvalidMethod

What it means

AddFactoryMethodAndValidateArguments must resolve a constructor or factory method to hold the instance's construction arguments. When the InstanceDescriptor's MemberInfo is neither a ConstructorInfo, a MethodInfo, nor absent (default-ctor path), and the value type is not a struct handled above, the reader cannot represent the construction and throws XamlObjectReaderException.

Solutions

  1. Fix the TypeConverter's ConvertTo(ITypeDescriptorContext, InstanceDescriptor) to return a ConstructorInfo or static MethodInfo member.
  2. If the value truly uses default construction, return an InstanceDescriptor with a null MemberInfo and empty arguments.
  3. Update/replace the third-party converter with one compatible with System.Xaml's XamlSchemaContext.

Example fix

// before
return new InstanceDescriptor(typeof(MyType).GetField("Instance"), Array.Empty<object>());
// after
var ctor = typeof(MyType).GetConstructor(Type.EmptyTypes);
return new InstanceDescriptor(ctor, null, true);
Defensive patterns

Strategy: type-guard

Validate before calling

static void ValidateDescriptor(InstanceDescriptor d) {
  if (d?.MemberInfo is not null && d.MemberInfo is not (ConstructorInfo or MethodInfo))
    throw new InvalidOperationException("InstanceDescriptor member must be a ctor or method.");
}

Type guard

bool HasInvocableMember(InstanceDescriptor d) => d?.MemberInfo is null or ConstructorInfo or MethodInfo;

Try / catch

try { using var r = new XamlObjectReader(instance); }
catch (XamlObjectReaderException ex) when (ex.Message.Contains("InvalidMethod")) { /* fix converter or use default ctor */ }

Prevention

When it happens

Trigger: Reading an instance whose InstanceDescriptor.MemberInfo is a non-invocable member (FieldInfo, PropertyInfo, EventInfo) for a reference type — the final else branch at XamlObjectReader.cs:1265-1267.

Common situations: Custom TypeConverters building InstanceDescriptor from a static field or property; third-party types whose converters were written for other serializers; assembly trimming/mismatch making the expected constructor unavailable so only a field member remains.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlObjectReader.cs:1267

                    Properties.Add(new MemberMarkupInfo
                    {
                        XamlNode = new XamlNode(XamlNodeType.StartMember, XamlLanguage.FactoryMethod),
                        IsFactoryMethod = true,
                        Children = { new ValueMarkupInfo() { XamlNode = new XamlNode(XamlNodeType.Value, methodName) } }
                    });
                }
                else if (valueType.IsValueType)
                {
                    if (arguments is not null && arguments.Count > 0)
                    {
                        throw new XamlObjectReaderException(SR.ObjectReaderInstanceDescriptorIncompatibleArguments);
                    }

                    return;
                }
                else
                {
                    throw new XamlObjectReaderException(SR.ObjectReaderInstanceDescriptorInvalidMethod);
                }

                if (arguments is not null)
                {
                    if (arguments.Count != methodParams.Length)
                    {
                        throw new XamlObjectReaderException(SR.ObjectReaderInstanceDescriptorIncompatibleArguments);
                    }

                    int argPos = 0;
                    foreach (var argument in arguments)
                    {
                        var parameterInfo = methodParams[argPos++];
                        if (argument is null)
                        {
                            if (parameterInfo.ParameterType.IsValueType)
                            {
                                if (!(parameterInfo.ParameterType.IsGenericType &&

View on GitHub (pinned to 81131a70a4)