{"record":{"id":"8f8856a718b47623","repo":"dotnet/wpf","slug":"cannot-remove-signature-from-read-only-file","errorCode":null,"errorMessage":"Cannot remove signature from read-only file.","messagePattern":"Cannot remove signature from read-only file\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/PackageDigitalSignatureManager.cs","lineNumber":687,"sourceCode":"\n                        if (exitOnFailure)\n                            break;\n                    }\n                }\n            }\n\n            return result;\n        }\n\n        /// <summary>\n        /// Remove a signature\n        /// </summary>\n        /// <param name=\"signatureUri\">signature to remove</param>\n        /// <remarks>Caller should call Package.Flush() in order to persist changes.</remarks>\n        public void RemoveSignature(Uri signatureUri)\n        {\n            if (ReadOnly)\n                throw new InvalidOperationException(SR.CannotRemoveSignatureFromReadOnlyFile);\n\n            ArgumentNullException.ThrowIfNull(signatureUri);\n\n            // empty?\n            if (!IsSigned)      // calls EnsureSignatures for us\n                return;\n\n            // find the signature\n            int index = GetSignatureIndex(signatureUri);\n            if (index < 0)\n                return;\n\n            try\n            {\n                Debug.Assert(index < _signatures.Count);\n\n                //After this signature is removed the total number of signatures remaining will\n                //be _signatures.Count - 1. If this count is zero, then additional clean up needs","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/PackageDigitalSignatureManager.cs#L669-L705","documentation":"PackageDigitalSignatureManager.RemoveSignature(Uri) refuses to modify a package opened in read-only mode. The manager exposes ReadOnly and throws InvalidOperationException before touching the signatures, since a read-only Package cannot have parts or relationships deleted. Caller should call Package.Flush() afterward to persist successful removals.","triggerScenarios":"Calling RemoveSignature(uri) on a manager whose underlying Package was opened with FileAccess.Read or FileMode.Open + FileAccess.Read, leaving ReadOnly == true.","commonSituations":"Opening a .oxps/.docx-like OPC package from a read-only share, from a stream the caller only has read access to, or with Package.Open(path, FileMode.Open, FileAccess.Read) and then trying to edit signatures.","solutions":["Reopen the package with FileAccess.ReadWrite (e.g. Package.Open(path, FileMode.Open, FileAccess.ReadWrite)) before calling RemoveSignature.","Check PackageDigitalSignatureManager.ReadOnly before calling and surface a clear message or copy the package to a writable location first.","If the source file itself is locked or on read-only media, copy it locally, clear the read-only attribute, and open read-write."],"exampleFix":"// before\nusing Package pkg = Package.Open(path, FileMode.Open, FileAccess.Read);\nvar mgr = new PackageDigitalSignatureManager(pkg);\nmgr.RemoveSignature(sigUri); // InvalidOperationException\n// after\nusing Package pkg = Package.Open(path, FileMode.Open, FileAccess.ReadWrite);\nvar mgr = new PackageDigitalSignatureManager(pkg);\nmgr.RemoveSignature(sigUri);\npkg.Flush();","handlingStrategy":"validation","validationCode":"if (mgr.ReadOnly) throw new InvalidOperationException(\"Package is read-only; reopen with FileAccess.ReadWrite before removing signatures.\");\nmgr.RemoveSignature(signatureUri);","typeGuard":"bool CanModify(PackageDigitalSignatureManager mgr) => !mgr.ReadOnly;","tryCatchPattern":"try { mgr.RemoveSignature(uri); pkg.Flush(); }\ncatch (InvalidOperationException ex) { /* read-only package: reopen writable or report */ }","preventionTips":["Always open packages with FileAccess.ReadWrite when the workflow mutates signatures.","Check ReadOnly before any Remove*/Sign call.","Remember to call Package.Flush() after mutation or changes stay in memory."],"tags":["wpf","packaging","read-only","invalid-operation","digital-signature"],"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"}