dotnet/wpf · error · ArgumentException

SR.SavedContextSchemaContextMismatch

Error message

SR.SavedContextSchemaContextMismatch

What it means

ArgumentException thrown by XamlObjectWriter.Initialize (reached from SerializeObject) when a non-null XamlSavedContext is supplied but its SchemaContext differs from the schemaContext parameter. The writer requires one consistent schema context across the reader/writer pair, otherwise type resolution would be inconsistent.

Solutions

  1. Pass the same XamlSchemaContext instance used to create the savedContext: schemaContext == savedContext.SchemaContext must hold by reference.
  2. Reuse a single shared XamlSchemaContext across the whole load/save pipeline instead of constructing new ones per component.
  3. If contexts must differ, rebuild the saved context from a reader created with the writer's schema context.
  4. Pass null savedContext if you do not need the saved context, letting the writer use the given schemaContext alone.

Example fix

// before
var shared = new XamlSchemaContext();
var other = new XamlSchemaContext();
var writer = new XamlObjectWriter(shared, settings);
writer.Initialize(savedContextFrom(other), shared, settings); // mismatch
// after
var shared = new XamlSchemaContext();
var writer = new XamlObjectWriter(shared, settings);
writer.Initialize(savedContextFrom(shared), shared, settings); // same instance
Defensive patterns

Strategy: validation

Validate before calling

if (savedContext != null && !ReferenceEquals(schemaContext, savedContext.SchemaContext))
    throw new InvalidOperationException("schemaContext must be the same instance as savedContext.SchemaContext.");

Type guard

static bool ContextsMatch(XamlSchemaContext sc, XamlSavedContext saved) => saved == null || ReferenceEquals(sc, saved.SchemaContext);

Try / catch

try { writer.Initialize(schemaContext, savedContext, settings); }
catch (ArgumentException ex) when (ex.ParamName == "schemaContext") { RebuildPipelineWithSharedContext(); }

Prevention

When it happens

Trigger: Calling the internal Initialize/SerializeObject path with a XamlSavedContext captured from a reader built on a different XamlSchemaContext instance than the one passed to Initialize (reference inequality, not just inequality of settings).

Common situations: Mixing readers and writers constructed with separately created XamlSchemaContext instances; copying a saved context between two XAML load operations that each built their own schema context; refactoring that split reader/writer construction across components.

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


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

Appendix: source

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

        {
            ArgumentNullException.ThrowIfNull(savedContext);
            if (savedContext.SchemaContext is null)
            {
                throw new ArgumentException(SR.SavedContextSchemaContextNull, nameof(savedContext));
            }

            Initialize(savedContext.SchemaContext, savedContext, settings);
        }

        private void Initialize(XamlSchemaContext schemaContext, XamlSavedContext savedContext, XamlObjectWriterSettings settings)
        {
            _inDispose = false;
            // ObjectWriter must be passed in a non-null SchemaContext.  We check that here, since the CreateContext method
            // will create one if a null SchemaContext was passed in.
            ArgumentNullException.ThrowIfNull(schemaContext);
            if (savedContext is not null && schemaContext != savedContext.SchemaContext)
            {
                throw new ArgumentException(SR.SavedContextSchemaContextMismatch, nameof(schemaContext));
            }

            if (settings is not null)
            {
                _afterBeginInitHandler = settings.AfterBeginInitHandler;
                _beforePropertiesHandler = settings.BeforePropertiesHandler;
                _afterPropertiesHandler = settings.AfterPropertiesHandler;
                _afterEndInitHandler = settings.AfterEndInitHandler;

                _xamlSetValueHandler = settings.XamlSetValueHandler;

                _rootObjectInstance = settings.RootObjectInstance;
                _skipDuplicatePropertyCheck = settings.SkipDuplicatePropertyCheck;
                _skipProvideValueOnRoot = settings.SkipProvideValueOnRoot;
                _preferUnconvertedDictionaryKeys = settings.PreferUnconvertedDictionaryKeys;
            }

            XAML3.INameScope rootNameScope = settings?.ExternalNameScope;

View on GitHub (pinned to 81131a70a4)