dotnet/wpf · error · XamlObjectReaderException

SR.ObjectReaderTypeIsNested

Error message

SR.ObjectReaderTypeIsNested

What it means

XamlObjectReader throws this during round-trip validation when the type of an object in the graph is a nested (compiler-generated or manually nested) type. XAML cannot declare a nested type via markup (no xml-namespaced reference form), so it refuses to read the graph to avoid producing invalid XAML.

Solutions

  1. Move the type out to a top-level (non-nested) public class
  2. Replace closure/anonymous-type instances with named top-level types before reading
  3. Add a TypeConverter so the value can be expressed as a string/extension instead of element markup
  4. Exclude the nested-typed property from the graph (e.g. [XamlSerializationVisibility] / ignore)

Example fix

// before
public class Outer { private class Payload { public int X; } }
// after: move to its own file
public class Payload { public int X; }
Defensive patterns

Strategy: type-guard

Validate before calling

if (type.IsNested) throw new InvalidOperationException($"{type.FullName} is nested and cannot roundtrip via XAML");

Type guard

bool IsXamlRoundtrippable(Type t) => !t.IsNested && !t.IsGenericType && (t.IsPublic || t.IsVisible);

Try / catch

try { using var r = new XamlObjectReader(obj); ... } catch (XamlObjectReaderException ex) when (ex.Message.Contains("TypeIsNested")) { /* hoist type or strip property */ }

Prevention

When it happens

Trigger: new XamlObjectReader(obj) where the graph contains an instance whose System.Xaml XamlType.UnderlyingType.IsNested is true (e.g. a lambda/closure display class or a class declared inside another class) and the type cannot round-trip otherwise.

Common situations: Serializing graphs that captured anonymous-type or closure instances; passing objects created inside methods (compiler-generated nested classes); types intentionally nested for encapsulation; deserializing object trees built with LINQ.

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


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

Appendix: source

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

            private static void CheckTypeCanRoundtrip(ObjectMarkupInfo objInfo)
            {
                var xamlType = objInfo.XamlNode.XamlType;
                if (!xamlType.IsConstructible)
                {
                    foreach (var property in objInfo.Properties)
                    {
                        if (((MemberMarkupInfo)property).IsFactoryMethod && !xamlType.UnderlyingType.IsNested)
                        {
                            // this is the case when the class has no public constructor we can use but contains a factory method
                            // and the class is not nested

                            return;
                        }
                    }

                    if (xamlType.UnderlyingType.IsNested)
                    {
                        throw new XamlObjectReaderException(SR.Format(SR.ObjectReaderTypeIsNested, xamlType.Name));
                    }
                    else
                    {
                        throw new XamlObjectReaderException(SR.Format(SR.ObjectReaderTypeCannotRoundtrip, xamlType.Name));
                    }
                }
            }

            public void AssignName(SerializerContext context)
            {
                if (Name is null)
                {
                    Name = context.AllocateIdentifier();
                    AddNameProperty(context);
                }
            }

            public void AssignName(string name, SerializerContext context)

View on GitHub (pinned to 81131a70a4)