dotnet/wpf · error · InvalidOperationException
SR.DocumentStreamMustBeFileSource
Error message
SR.DocumentStreamMustBeFileSource
What it means
SwapWithOriginal throws InvalidOperationException with SR.DocumentStreamMustBeFileSource when the original DocumentStream has no _xpsFileToken, i.e. the original was not created from an XPS file on disk. Swapping a temporary stream back requires both sides to be file-backed.
Solutions
- Create the original DocumentStream from a file path (file URI) so it has an XPS file token before using swap logic.
- For stream-sourced documents, persist to a temporary file first, then perform file-based operations.
- Skip swap/commit operations for non-file-backed documents and handle them via an alternate save path.
Example fix
// before var doc = XpsDocument(... from MemoryStream ...); // later SwapWithOriginal fails // after write stream to temp .xps file; open DocumentStream from the file path, then swap
Defensive patterns
Strategy: validation
Validate before calling
bool originalIsFileBacked = docStream.Original != null && docStream.Original.Location != null && docStream.Original.Location.IsFile;
Try / catch
try { docStream.SwapWithOriginal(); }
catch (InvalidOperationException) { /* persist stream to temp file, retry */ } Prevention
- Create originals from file URIs; persist in-memory XPS to a temp file before file-based operations.
- Route stream-sourced documents to stream-based save paths.
When it happens
Trigger: SwapWithOriginal() called where the temporary stream is valid but its _original was created from a memory stream or non-file source (_original._xpsFileToken == null).
Common situations: Opening an XPS package from a stream (e.g. downloaded or in-memory XPS) and then attempting internal save/commit flows that assume a file-backed original.
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
- SR.DocumentStreamMustBeTemporary
- SR.PackageControllerStreamCorruption
- Image_OriginalStreamReadOnly
- ReachPackaging_SigningDoesNotMeetPolicy
- SR.Format(SR.CanOnlyHaveOneChild, typeof(PageContent)…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d7b0f078ccb33fdd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/DocumentStream.cs:508
/// 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);
ThrowIfInvalidXpsFileForSave(_xpsFileToken.Location);
ThrowIfInvalidXpsFileForOpen(_original._xpsFileToken.Location);
string original = _original._xpsFileToken.Location.LocalPath;View on GitHub (pinned to 81131a70a4)