dotnet/wpf · error · XamlObjectReaderException

SR.ObjectReaderInstanceDescriptorIncompatibleArgumentTypes

Error message

SR.ObjectReaderInstanceDescriptorIncompatibleArgumentTypes

What it means

Each argument of the InstanceDescriptor is type-checked against the corresponding method parameter: a null argument is only allowed for reference types or Nullable<T>, and non-null arguments must be assignable to the parameter type. Violating either rule throws XamlObjectReaderException naming the argument type and the expected parameter type.

Solutions

  1. Replace null with a concrete value of the parameter type (or default(T)) when the parameter is a non-nullable value type.
  2. Change the constructor/parameter to Nullable<T> or a reference type if a null argument is legitimately required.
  3. Convert the argument to the exact parameter type before building the InstanceDescriptor (e.g. Convert.ChangeType or explicit cast).

Example fix

// before
return new InstanceDescriptor(ctor, new object[] { null, name }); // param 0 is int
// after
return new InstanceDescriptor(ctor, new object[] { 0, name }); // supply valid int
// or change ctor to accept int? for nullability
Defensive patterns

Strategy: validation

Validate before calling

var pars = ((MethodBase)descriptor.MemberInfo).GetParameters();
for (int i = 0; i < pars.Length; i++) {
  var arg = descriptor.Arguments[i];
  if (arg is null && pars[i].ParameterType.IsValueType && Nullable.GetUnderlyingType(pars[i].ParameterType) is null)
    throw new InvalidOperationException($"Argument {i}: null not allowed for {pars[i].ParameterType}.");
  if (arg is not null && !pars[i].ParameterType.IsInstanceOfType(arg))
    throw new InvalidOperationException($"Argument {i} type mismatch: {arg.GetType()} vs {pars[i].ParameterType}.");
}

Type guard

bool ArgsMatchParams(InstanceDescriptor d) => d.MemberInfo is not MethodBase m || m.GetParameters().Zip(d.Arguments.Cast<object?>()).All(p => p.Second is null ? !(p.First.ParameterType.IsValueType && Nullable.GetUnderlyingType(p.First.ParameterType) is null) : p.First.ParameterType.IsInstanceOfType(p.Second));

Try / catch

try { using var r = new XamlObjectReader(instance); }
catch (XamlObjectReaderException ex) when (ex.Message.Contains("IncompatibleArgumentTypes")) { /* coerce or null-fix arguments before rebuilding descriptor */ }

Prevention

When it happens

Trigger: Reading an instance whose InstanceDescriptor passes null for a non-nullable value-type parameter (XamlObjectReader.cs:1281-1290), or an argument whose runtime type is not assignable to the parameter type (XamlObjectReader.cs:1292-1295).

Common situations: Converters passing null for struct parameters (int, Guid, enums) after refactorings; passing a derived/base type or boxed incompatible type (e.g. double where int is expected); signature changes from int to Nullable<int> or vice versa leaving stale descriptor code.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

                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 &&
                                    parameterInfo.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                                {
                                    throw new XamlObjectReaderException(SR.Format(SR.ObjectReaderInstanceDescriptorIncompatibleArgumentTypes, "null", parameterInfo.ParameterType));
                                }
                            }
                        }
                        else if (!parameterInfo.ParameterType.IsAssignableFrom(argument.GetType()))
                        {
                            throw new XamlObjectReaderException(SR.Format(SR.ObjectReaderInstanceDescriptorIncompatibleArgumentTypes, argument.GetType(), parameterInfo.ParameterType));
                        }
                    }
                }
            }

            private void AddArgumentsMembers(ICollection arguments, SerializerContext context)
            {
                if (arguments is not null && arguments.Count > 0)
                {
                    var itemsProperty = new MemberMarkupInfo
                    {
                        XamlNode = new XamlNode(XamlNodeType.StartMember, XamlLanguage.Items)

View on GitHub (pinned to 81131a70a4)