{"record":{"id":"d2e353f228f7f0c8","repo":"dotnet/wpf","slug":"stg-e-cantsave","errorCode":"STG_E_CANTSAVE","errorMessage":"The only IPersistFile operation supported by the component is Load.","messagePattern":"The only IPersistFile operation supported by the component is Load\\.","errorType":"exception","errorClass":"COMException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/XpsFilter.cs","lineNumber":459,"sourceCode":"\n        /// <summary>\n        /// Saves a copy of the object into the specified file.\n        /// </summary>\n        /// <param name=\"pszFileName\">\n        /// A zero-terminated string containing the absolute path \n        /// of the file to which the object is saved.\n        /// </param>\n        /// <param name=\"fRemember\">\n        /// Indicates whether pszFileName is to be used as the current working file. \n        /// </param>\n        /// <remarks>\n        /// On the odd chance that this link is still valid when it's needed, \n        /// expected error codes are described at\n        /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/da9581e8-98c7-4592-8ee1-a1bc8232635b.asp\n        /// </remarks>\n        void IPersistFile.Save(string pszFileName, bool fRemember)\n        {\n            throw new COMException(SR.FilterIPersistFileIsReadOnly, NativeMethods.STG_E_CANTSAVE);\n        }\n\n        /// <summary>\n        /// Notifies the object that it can write to its file.\n        /// </summary>\n        /// <param name=\"pszFileName\">\n        /// The absolute path of the file where the object was previously saved. \n        /// </param>\n        /// <remarks>\n        /// On the odd chance that this link is still valid when it's needed, \n        /// expected error codes are described at\n        /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/da9581e8-98c7-4592-8ee1-a1bc8232635b.asp\n        /// This function should always return S_OK when Save is not supported.\n        /// </remarks>\n        void IPersistFile.SaveCompleted(string pszFileName)\n        {\n            return; // return S_OK\n        }","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/XpsFilter.cs#L441-L477","documentation":"IPersistFile.Save on XpsFilter is deliberately unimplemented: a filter is read-only, so the explicit interface method immediately throws COMException with STG_E_CANTSAVE and the message SR.FilterIPersistFileIsReadOnly. There is no code path that saves; the operation is unsupported by design.","triggerScenarios":"Calling IPersistFile.Save (or SaveCompleted patterns that assume writability) on an XpsFilter instance obtained as IPersistFile.","commonSituations":"Generic persistence plumbing that round-trips every IPersistFile component; test harnesses exercising all interface members.","solutions":["Do not call Save on the filter; treat it as load-only","Gate Save calls behind a capability check / feature flag for writable persistence","Use the actual storage (XPS writer APIs) to produce files instead of the filter"],"exampleFix":"// before\n((IPersistFile)filter).Save(path, true);\n// after\n// XpsFilter is read-only; write XPS via XpsDocument instead\nusing (var doc = new XpsDocument(path, FileAccess.Write)) { /* write */ }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { ((IPersistFile)filter).Save(path, true); }\ncatch (COMException ex) when (ex.HResult == NativeMethods.STG_E_CANTSAVE)\n{ /* read-only component: use writer APIs instead */ }","preventionTips":["Treat filters as load-only; never wire them into save pipelines","Check component capabilities before generic IPersistFile save calls","Write XPS via XpsDocument, not the filter"],"tags":["com","unsupported","wpf","read-only"],"backgroundTag":"unsupported-operation","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"}