unoplatform/uno · error · XamlObjectReaderException

instance type '{0}' must be public and non-nested.

Error message

instance type '{0}' must be public and non-nested.

What it means

Thrown by the XamlObjectReader constructor when the type of the instance object is not public (including nested types). XamlObjectReader uses reflection and XAML requires public, non-nested types for serialization so that the type can be referenced from markup and instantiated by name; a non-public type cannot be meaningfully written to XAML.

Source

Thrown at src/SourceGenerators/System.Xaml/System.Xaml/XamlObjectReader.cs:96

			if (schemaContext == null)
				throw new ArgumentNullException ("schemaContext");
			// FIXME: special case? or can it be generalized? In .NET, For Type instance Instance returns TypeExtension at root StartObject, while for Array it remains to return Array.
			if (instance is Type)
				instance = new TypeExtension ((Type) instance);

			// See also Instance property for this weirdness.
			this.root_raw = instance;
			instance = TypeExtensionMethods.GetExtensionWrapped (instance);
			this.root = instance;

			sctx = schemaContext;
//			this.settings = settings;

			// check type validity. Note that some checks also needs done at Read() phase. (it is likely FIXME:)
			if (instance != null) {
				var type = new InstanceContext (instance).GetRawValue ().GetType ();
				if (!type.IsPublic)
					throw new XamlObjectReaderException (String.Format (CultureInfo.InvariantCulture, "instance type '{0}' must be public and non-nested.", type));
				var xt = SchemaContext.GetXamlType (type);
				if (xt.ConstructionRequiresArguments && !xt.GetConstructorArguments ().Any () && xt.TypeConverter == null)
					throw new XamlObjectReaderException (String.Format (CultureInfo.InvariantCulture, "instance type '{0}' has no default constructor.", type));
			}

			value_serializer_context = new ValueSerializerContext (new PrefixLookup (sctx), sctx, null);
			new XamlObjectNodeIterator (instance, sctx, value_serializer_context).PrepareReading ();
		}
		
		bool is_eof;
		object root, root_raw;
		XamlSchemaContext sctx;
//		XamlObjectReaderSettings settings;
		IValueSerializerContext value_serializer_context;

		IEnumerator<NamespaceDeclaration> ns_iterator;
		IEnumerator<XamlNodeInfo> nodes;

View on GitHub (pinned to 0418340488)

Solutions

  1. Make the instance type public and non-nested so it can be serialized to XAML.
  2. If the type must stay internal, map it to a public XAML surrogate type via a custom XamlSchemaContext or TypeConverter.
  3. Do not pass non-public types to XamlObjectReader; serialize a public wrapper/proxy instead.

Example fix

// before
internal class MyInternalData { public string Value { get; set; } }
var reader = new XamlObjectReader(new MyInternalData { Value = "x" }, sctx);

// after
public class MyPublicData { public string Value { get; set; } }
var reader = new XamlObjectReader(new MyPublicData { Value = "x" }, sctx);
Defensive patterns

Strategy: validation

Validate before calling

var type = instance.GetType();
if (!type.IsPublic)
    throw new InvalidOperationException($"{type} must be public for XAML serialization.");
var reader = new XamlObjectReader(instance, sctx);

Type guard

static bool IsXamlSerializableType(Type t) => t.IsPublic && !t.IsNested;

Try / catch

try { var reader = new XamlObjectReader(obj, sctx); }
catch (XamlObjectReaderException) { /* map to a public surrogate type */ }

Prevention

When it happens

Trigger: Constructing new XamlObjectReader(instance, sctx) where instance.GetType().IsPublic is false. This includes private, internal, protected, and nested classes.

Common situations: Serializing internal helper classes, anonymous types, or nested classes through XamlObjectReader. Passing a domain-model object that was declared internal for encapsulation. Attempting to round-trip test fixtures or DTOs that are not public.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/231cb3c7051f40e7. Report an issue: GitHub.