{"record":{"id":"11729e51e437a12f","repo":"dotnet/wpf","slug":"sr-documentstreammustbexpsfile","errorCode":null,"errorMessage":"SR.DocumentStreamMustBeXpsFile","messagePattern":"SR\\.DocumentStreamMustBeXpsFile","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/DocumentStream.cs","lineNumber":958,"sourceCode":"                e);\n        }            \n    }\n\n    /// <summary>\n    /// Will throw if location is not a XpsDocument file.\n    /// </summary>\n    /// <exception cref=\"System.ArgumentNullException\"/>\n    /// <exception cref=\"System.InvalidOperationException\"/>\n    /// <exception cref=\"System.InvalidDataException\"/>\n    /// <param name=\"location\"></param>\n    private static void ThrowIfInvalidXpsFileForSave(Uri location)\n    {\n        ThrowIfInvalidXpsFileForOpen(location);\n\n        if (!Path.GetExtension(location.LocalPath).Equals(\n            XpsFileExtension, StringComparison.OrdinalIgnoreCase))\n        {\n            throw new InvalidDataException(\n                SR.DocumentStreamMustBeXpsFile);\n        }\n    }\n\n    /// <summary>\n    /// Will throw if location is not a valid file.\n    /// </summary>\n    /// <exception cref=\"System.ArgumentNullException\"/>\n    /// <exception cref=\"System.InvalidOperationException\"/>\n    private static void ThrowIfInvalidXpsFileForOpen(Uri location)\n    {\n        ArgumentNullException.ThrowIfNull(location);\n        if (!location.IsFile)\n        {\n            throw new InvalidOperationException(\n                SR.DocumentStreamMustBeFileSource);\n        }\n    }","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/DocumentStream.cs#L940-L976","documentation":"ThrowIfInvalidXpsFileForSave throws InvalidDataException when the target file's extension is not .xps (case-insensitive comparison against XpsFileExtension). Save operations require the destination to be an XPS file; saving to a non-XPS extension would produce an incorrectly named package.","triggerScenarios":"Save/commit flows (Copy, SwapWithOriginal, MakeTempFile) given a location URI whose LocalPath extension is not '.xps', e.g. '.zip', '.oxps', or a no-extension temp name.","commonSituations":"Users typing a filename with a wrong or missing extension in a Save dialog; code generating temp file names without appending .xps; renaming documents to .zip to inspect contents then trying to save back.","solutions":["Ensure the save target path ends with the .xps extension before initiating the save.","When generating temp file names, append .xps (e.g. Path.ChangeExtension(path, \".xps\")).","Validate user-supplied file names in the save dialog and correct/append the extension."],"exampleFix":"// before\nvar path = Path.Combine(tempDir, Guid.NewGuid().ToString()); // no extension\n// after\nvar path = Path.ChangeExtension(Path.Combine(tempDir, Guid.NewGuid().ToString()), \".xps\");","handlingStrategy":"validation","validationCode":"bool isXpsTarget = string.Equals(Path.GetExtension(location.LocalPath), \".xps\", StringComparison.OrdinalIgnoreCase);","typeGuard":null,"tryCatchPattern":"try { SaveTo(location); }\ncatch (InvalidDataException) { location = new Uri(Path.ChangeExtension(location.LocalPath, \".xps\")); SaveTo(location); }","preventionTips":["Append .xps to every generated temp filename used as a save target.","Sanitize Save dialog file names to enforce the .xps extension."],"tags":["xps","invalid-data","file-extension","save"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}