dotnet/wpf · error · XpsSerializationException

SR.ReachSerialization_FixedDocumentInDocument

Error message

SR.ReachSerialization_FixedDocumentInDocument

What it means

RegisterDocumentStart maintains the XPS document state machine: a FixedDocument cannot begin while another document is already open (_documentStartState). If RegisterDocumentStart is called twice without an intervening RegisterDocumentEnd, XpsSerializationException(SR.ReachSerialization_FixedDocumentInDocument) is thrown — nested FixedDocuments are illegal in XPS.

Solutions

  1. Call RegisterDocumentEnd before starting the next document — strictly alternate document start/end.
  2. Nest pages correctly: within one document use RegisterPageStart/RegisterPageEnd, not another document start.
  3. Guard your serializer with a flag so RegisterDocumentStart is invoked once per FixedDocument.
  4. Prefer higher-level APIs (XpsDocumentWriter with DocumentPaginator) that manage the state machine for you.

Example fix

// before
manager.RegisterDocumentStart();
manager.RegisterDocumentStart(); // nested document
// after
manager.RegisterDocumentStart();
// ... write pages ...
manager.RegisterDocumentEnd();
manager.RegisterDocumentStart(); // next document
Defensive patterns

Strategy: validation

Validate before calling

if (documentOpen)
    throw new InvalidOperationException("RegisterDocumentStart called while a FixedDocument is already open; call RegisterDocumentEnd first.");

Try / catch

try
{
    manager.RegisterDocumentStart();
}
catch (System.Windows.Xps.XpsSerializationException ex) when (ex.Message.Contains("document"))
{
    // recover: end the current document, then restart
    manager.RegisterDocumentEnd();
    manager.RegisterDocumentStart();
}

Prevention

When it happens

Trigger: Calling RegisterDocumentStart twice without RegisterDocumentEnd in between — typically from a custom serializer that writes a second <FixedDocument> before closing the first, or from duplicate event/serialization callbacks.

Common situations: Hand-rolled XPS writers built on IXpsSerializationManager; pagination code that restarts a document per page instead of using RegisterPageStart; re-entrant serialization triggered by print events.

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/fd1d5c5724209822. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/manager/XpsSerializationManager.cs:840

        /// </param>
        internal
        override
        void
        AddRelationshipToCurrentPage(
            Uri targetUri,
            string relationshipName
            )
        {
            _packagingPolicy?.RelateResourceToCurrentPage(targetUri, relationshipName);
        }

        internal
        void
        RegisterDocumentStart()
        {
            if( _documentStartState )
            {
                throw new XpsSerializationException(SR.ReachSerialization_FixedDocumentInDocument);
            }
            if( _pageStartState)
            {
                throw new XpsSerializationException(SR.ReachSerialization_FixedDocumentInPage);
            }
            //
            // Entering Document  Started state
            //
            _documentStartState = true;
            //
            // Increment the number of documents serialized
            //
            _documentNumber += 1;
            //
            // Clearing the number of pages for this document
            //
            _pageNumber = 0;
        }

View on GitHub (pinned to 81131a70a4)