dotnet/wpf · error · InvalidOperationException

SR.ObjectWriterTypeNotAllowed

Error message

SR.ObjectWriterTypeNotAllowed

What it means

InvalidOperationException thrown by XamlObjectWriter.GetXamlType when SchemaContext.GetXamlType(clrType) returns null, i.e. the schema context has no XAML type mapping for the given CLR type. The object writer cannot serialize/instantiate an unmapped type, so it fails with a message naming the schema context and the offending type.

Solutions

  1. Register the CLR type with the schema context (e.g. use a XamlSchemaContext whose reference assemblies include the type's assembly, or a custom XamlSchemaContext with GetXamlType override).
  2. Make the type public with a parameterless constructor so the default type mapping can find it.
  3. Pass the correct assemblies to XamlSchemaContext(IEnumerable<Assembly>) so the type is resolvable.
  4. Verify with SchemaContext.GetXamlType(clrType) != null before writing objects of that type.

Example fix

// before
var sc = new XamlSchemaContext(); // does not know MyAssembly
writer.GetXamlType(typeof(MyControls.CustomControl)); // InvalidOperationException
// after
var sc = new XamlSchemaContext(new[] { typeof(MyControls.CustomControl).Assembly });
var xt = sc.GetXamlType(typeof(MyControls.CustomControl)); // non-null
Defensive patterns

Strategy: validation

Validate before calling

if (schemaContext.GetXamlType(clrType) == null)
    throw new InvalidOperationException($"{clrType} is not mapped in {schemaContext.GetType()}.");

Type guard

static bool IsMapped(XamlSchemaContext sc, Type t) => sc.GetXamlType(t) != null;

Try / catch

try { processType(clrType); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not allowed")) { RegisterAssemblyAndRetry(clrType); }

Prevention

When it happens

Trigger: Calling GetXamlType (reached from WriteStartObject root-instance handling and other paths) with a CLR type that the XamlSchemaContext does not map — e.g. types outside the loaded assemblies, non-public types, or types not visible to the context's assembly list.

Common situations: Using a restricted XamlSchemaContext that only knows a subset of assemblies; loading XAML in a trimmed/AOT-published app where the type's assembly was cut; internal or private types without proper accessibility for the schema context; assembly version changes renaming or removing the type.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/XamlObjectWriter.cs:1087

        /// </summary>
        private object GetKeyFromInstance(object instance, XamlType instanceType, IAddLineInfo lineInfo)
        {
            XamlMember keyProperty = instanceType.GetAliasedProperty(XamlLanguage.Key);
            if (keyProperty is null || instance is null)
            {
                throw lineInfo.WithLineInfo(new XamlObjectWriterException(SR.Format(SR.MissingKey, instanceType.Name)));
            }

            object key = Runtime.GetValue(instance, keyProperty);
            return key;
        }

        private XamlType GetXamlType(Type clrType)
        {
            XamlType result = SchemaContext.GetXamlType(clrType);
            if (result is null)
            {
                throw new InvalidOperationException(SR.Format(SR.ObjectWriterTypeNotAllowed,
                    SchemaContext.GetType(), clrType));
            }

            return result;
        }

        // These are the all the directives that affect Construction of object.
        private bool IsConstructionDirective(XamlMember xamlMember)
        {
            return xamlMember == XamlLanguage.Arguments
                || xamlMember == XamlLanguage.Base
                || xamlMember == XamlLanguage.FactoryMethod
                || xamlMember == XamlLanguage.Initialization
                || xamlMember == XamlLanguage.PositionalParameters
                || xamlMember == XamlLanguage.TypeArguments;
        }

        // BAML sometimes sends the x:base directive later than it should

View on GitHub (pinned to 81131a70a4)