dotnet/wpf · error · XamlObjectReaderException

SR.ObjectReaderInstanceDescriptorIncompatibleArguments

Error message

SR.ObjectReaderInstanceDescriptorIncompatibleArguments

What it means

When reconstructing XAML for a value type instance whose InstanceDescriptor supplied factory arguments, the reader must have a constructor/factory method to apply them to. For a value type with no matching constructor/factory member, positional arguments cannot be represented, so XamlObjectReaderException is thrown.

Solutions

  1. Return an InstanceDescriptor whose MemberInfo is a ConstructorInfo (or static factory MethodInfo) for value types, matching the argument list.
  2. If the descriptor intentionally uses a field/property member, supply an empty Arguments collection.
  3. Change the struct to expose a parameterless constructor and set properties, avoiding constructor arguments in the descriptor.

Example fix

// before
return new InstanceDescriptor(typeof(MyStruct).GetField("Default"), new object[] { 1, 2 }); // field member with args
// after
var ctor = typeof(MyStruct).GetConstructor(new[] { typeof(int), typeof(int) });
return new InstanceDescriptor(ctor, new object[] { 1, 2 }); // ctor matches argument count
Defensive patterns

Strategy: type-guard

Validate before calling

static void ValidateDescriptor(InstanceDescriptor d) {
  if (d?.MemberInfo is ConstructorInfo or MethodInfo) return;
  if (d?.Arguments is { Count: > 0 }) throw new InvalidOperationException("Non-ctor member with arguments is not serializable.");
}

Type guard

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

Try / catch

try { using var r = new XamlObjectReader(instance); }
catch (XamlObjectReaderException ex) when (ex.Message.Contains("IncompatibleArguments")) { /* fix the TypeConverter's InstanceDescriptor */ }

Prevention

When it happens

Trigger: Reading a value-type instance obtained through an InstanceDescriptor whose MemberInfo is not a constructor/method (e.g. a field/property member) while the descriptor's Arguments collection is non-empty — AddFactoryMethodAndValidateArguments, valueType.IsValueType branch (XamlObjectReader.cs:1256-1261).

Common situations: Custom TypeConverter.GetCreateInstanceDescriptor returning a descriptor whose member is a property/field with arguments; structs exposed through converters that try to pass constructor arguments via a non-constructor member; serialization of custom structs with required constructor parameters.

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/63076cd8cde4b4ee. Report an issue: GitHub.

Appendix: source

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

                    var declaringType = memberInfo.DeclaringType;
                    if (declaringType != valueType)
                    {
                        methodName = ConvertTypeAndMethodToString(declaringType, methodName, context);
                    }

                    // add factory method if there is one
                    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)

View on GitHub (pinned to 81131a70a4)