dotnet/wpf · error · XamlParseException
SR.CantAssignRootInstance
Error message
SR.CantAssignRootInstance
What it means
XamlParseException thrown by XamlObjectWriter.WriteStartObject when a root object instance was pre-supplied (via XamlObjectWriterSettings.RootObjectInstance) and the object writer reaches depth 1, but the root instance's type cannot be assigned to (does not implement/derive from) the XAML type of the root node in the node stream. The library refuses to substitute an incompatible root instance.
Solutions
- Make the RootObjectInstance type assignable to the XAML root type (implement the interface or derive from the declared root class).
- Change the XAML's root element type so it matches (or is a base of) the supplied root instance's type.
- Remove RootObjectInstance if the writer should instantiate the root itself from the node stream.
- Verify with SchemaContext.GetXamlType(rootInstance.GetType()).CanAssignTo(rootNodeType) before invoking the load.
Example fix
// before settings.RootObjectInstance = new Button(); // XAML root is <Window ...> var writer = new XamlObjectWriter(settings); // throws on WriteStartObject // after settings.RootObjectInstance = new Window(); // assignable to declared root type var writer = new XamlObjectWriter(settings);
Defensive patterns
Strategy: validation
Validate before calling
var declared = schemaContext.GetXamlType(rootNodeType);
if (!schemaContext.GetXamlType(settings.RootObjectInstance.GetType()).CanAssignTo(declared))
throw new InvalidOperationException("RootObjectInstance type not assignable to XAML root type."); Type guard
static bool RootAssignable(XamlSchemaContext sc, object rootInstance, XamlType rootType) =>
rootInstance == null || sc.GetXamlType(rootInstance.GetType())?.CanAssignTo(rootType) == true; Try / catch
try { xamlServices.Load(writer); }
catch (XamlParseException ex) when (ex.Message.Contains("root")) { RecreateWithoutRootInstance(); } Prevention
- Keep RootObjectInstance type in sync with the XAML root element.
- Validate CanAssignTo before starting the load when pre-assigning root instances.
- Update settings whenever the XAML root element type changes.
- Prefer letting the writer instantiate the root unless substitution is required.
When it happens
Trigger: Setting RootObjectInstance to an object whose CLR type cannot be assigned to the XamlType of the StartObject node being written at LiveDepth == 1, e.g. root instance is a Button while the stream declares a Window root.
Common situations: Pre-assigning a root instance in XamlObjectWriterSettings but loading XAML whose root element is a different type; refactoring XAML root elements without updating RootObjectInstance; plugin-style loading where the supplied instance type drifted from the serialized XAML.
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
- error
- MappingParseError(_scanner.Start, token, _token)
- message (InvalidOperationException)
- SR.Format(SR.TokenizerHelperExtraDataEncountered…
- SR.NameScopeOnRootInstance
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/fdc49bafbb7fa83d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/XamlObjectWriter.cs:375
// A Frame is pushed by either a AddNamespace or a WriteGet/StartObject
if (_context.CurrentType is not null)
{
_context.PushScope();
}
_context.CurrentType = xamlType;
// Don't create the Root Instance if we were given one in the settings.
// This is an important senario when a XamlObject loads a XamlDefinition of itself
// in it's constructor. The instance is already created (that is how we got into
// the constructor), now don't create the first StartObject use the existing instance.
//
if ((_context.LiveDepth == 1) && (_rootObjectInstance is not null))
{
XamlType rootType = GetXamlType(_rootObjectInstance.GetType());
if (!rootType.CanAssignTo(_context.CurrentType))
{
throw new XamlParseException(SR.Format(SR.CantAssignRootInstance,
rootType.GetQualifiedName(), xamlType.GetQualifiedName()));
}
_context.CurrentInstance = _rootObjectInstance;
if (_context.CurrentType.IsCollection || _context.CurrentType.IsDictionary)
{
_context.CurrentCollection = _rootObjectInstance;
}
Logic_BeginInit(_context);
}
}
public override void WriteEndObject()
{
ThrowIfDisposed();
// Deferring CheckingView on GitHub (pinned to 81131a70a4)