dotnet/wpf · error · XpsSerializationException

SR.ReachSerialization_MustHaveSerializationManager

Error message

SR.ReachSerialization_MustHaveSerializationManager

What it means

BeginSerializeObject (the property overload, reached via SerializeObject) requires an active SerializationManager on the async serializer. If SerializationManager is null — i.e. the serializer was created without a manager or StartSerialization was never called — an XpsSerializationException with SR.ReachSerialization_MustHaveSerializationManager is thrown before discovering property data.

Solutions

  1. Call StartSerialization (which attaches the serialization manager) before SerializeObject/BeginSerializeObject.
  2. Ensure the manager passed at construction is retained and not nulled before serialization completes.
  3. Create a fresh NGCSerializerAsync with a valid NgcSerializationManagerAsync for each document instead of reusing a finished instance.

Example fix

// before
serializer.SerializeObject(rootProperty); // no manager attached yet
// after
serializer.StartSerialization(packagingPolicy);
serializer.SerializeObject(rootProperty);
Defensive patterns

Strategy: validation

Validate before calling

if (serializer.SerializationManager == null)
    throw new InvalidOperationException("Call StartSerialization before SerializeObject.");

Type guard

bool ReadyToSerialize(NGCSerializerAsync s) => s.SerializationManager != null;

Try / catch

try { serializer.SerializeObject(property); }
catch (XpsSerializationException ex) {
    // reinitialize: serializer.StartSerialization(policy) then retry
}

Prevention

When it happens

Trigger: Calling BeginSerializeObject(serializedProperty) (via SerializeObject) on an NGCSerializerAsync whose SerializationManager property is null: serializer constructed without Initialize/manager, or EndSerialization/reset already tore down the manager.

Common situations: Reusing an NGCSerializerAsync instance across documents after EndSerialization cleared the manager; calling SerializeObject before StartSerialization in async XPS save pipelines.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/manager/NGCSerializerAsync.cs:124

        SerializeObject(
            SerializablePropertyContext serializedProperty
            )
        {
            BeginSerializeObject(serializedProperty);
        }

        internal
        virtual
        void
        BeginSerializeObject(
            SerializablePropertyContext serializedProperty
            )
        {
            ArgumentNullException.ThrowIfNull(serializedProperty);

            if (SerializationManager == null)
            {
                throw new XpsSerializationException(SR.ReachSerialization_MustHaveSerializationManager);
            }

            //
            // At this stage discover the graph of properties of the object that
            // need to be serialized
            //
            SerializableObjectContext serializableObjectContext = DiscoverObjectData(serializedProperty.Value,
                                                                                     serializedProperty);

            if(serializableObjectContext!=null)
            {
                //
                // Push the object at hand on the context stack
                //
                SerializationManager.GraphContextStack.Push(serializableObjectContext);

                NGCSerializerContext context = new NGCSerializerContext(this,
                                                                        serializableObjectContext,

View on GitHub (pinned to 81131a70a4)