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
- Move the type out to a top-level (non-nested) public class
- Replace closure/anonymous-type instances with named top-level types before reading
- Add a TypeConverter so the value can be expressed as a string/extension instead of element markup
- 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
- Avoid anonymous types/closures in serializable object graphs
- Keep XAML-serializable types top-level and public
- Add TypeConverters where element markup is not feasible
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
- ArgumentNullException(nameof(writer))
- InvalidOperationException(SR.Format(SR.XamlTypeNameCannotGet…
- (no message - parameterless InvalidOperationException)
- SR.Format(SR.DeferringLoaderNoSave…
- SR.Format(SR.MarkupWriter_CannotSerializeGenerictype…
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)