dotnet/wpf · error · InvalidOperationException

SR.DocumentStreamMustBeTemporary

Error message

SR.DocumentStreamMustBeTemporary

What it means

DocumentStream.SwapWithOriginal throws InvalidOperationException if the stream's _original reference is null, meaning this stream is not a temporary copy of another stream. Only temporary streams (created from an original) can be swapped back, so the operation is invalid on a directly opened stream.

Solutions

  1. Only call SwapWithOriginal on streams created as temporary copies of an original DocumentStream.
  2. Check that the stream is temporary before swapping; skip the call otherwise.
  3. Do not call SwapWithOriginal more than once on the same stream.

Example fix

// before
docStream.SwapWithOriginal();
// after
if (docStream.IsTemporary) docStream.SwapWithOriginal(); // only when backed by an original
Defensive patterns

Strategy: validation

Validate before calling

bool canSwap = docStream.IsTemporary && docStream.Original != null;

Try / catch

try { docStream.SwapWithOriginal(); }
catch (InvalidOperationException) { /* not a temporary stream; use alternate save path */ }

Prevention

When it happens

Trigger: Calling SwapWithOriginal() on a DocumentStream that was constructed directly from a file/stream rather than as a temporary working copy created via MakeTempFile/Copy.

Common situations: Developers calling internal swap logic on a plainly opened XPS document, or calling SwapWithOriginal twice (the first swap clears the temporary relationship).

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/DocumentStream.cs:503

    /// <exception cref="System.InvalidOperationException"/>
    /// <returns>False if the operation failed.</returns>
    /// <remarks>
    /// This method is inplace to work around issues with re-publishing
    /// XpsDocuments into the same file.  The intended use for the method is 
    /// to logically allow in place editing for the user.
    /// 
    /// After use this object is unusable and should be disposed as the
    /// temporary file is gone; it has become the original. In the event of an
    /// error while swapping the file, the file no longer becomes the original,
    /// but this object still becomes unusable.
    /// </remarks>
    internal bool SwapWithOriginal()
    {
        bool success = false;

        if (_original == null)
        {
            throw new InvalidOperationException(
                SR.DocumentStreamMustBeTemporary);
        }
        if (_original._xpsFileToken == null)
        {
            throw new InvalidOperationException(
                SR.DocumentStreamMustBeFileSource);
        }
        if (_xpsFileToken == null)
        {
            throw new InvalidOperationException(
                SR.DocumentStreamMustBeFileSource);
        }

        Trace.SafeWrite(
            Trace.File,
            "Begining file swap between {0} and {1}.",
            _xpsFileToken.Location,
            _original._xpsFileToken.Location);

View on GitHub (pinned to 81131a70a4)