{"record":{"id":"80b7be0e4a14e223","repo":"dotnet/wpf","slug":"sr-cannotchangepublishlicense","errorCode":null,"errorMessage":"SR.CannotChangePublishLicense","messagePattern":"SR\\.CannotChangePublishLicense","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs","lineNumber":198,"sourceCode":"        /// If <paramref name=\"publishLicense\"/> is null.\n        /// </exception>\n        /// <exception cref=\"FileFormatException\">\n        /// If the existing RM instance data in this file cannot be updated by the current version\n        /// of this class.\n        /// </exception>\n        /// <exception cref=\"InvalidOperationException\">\n        /// If the transform settings are fixed.\n        /// </exception>\n        internal void\n        SavePublishLicense(\n            PublishLicense publishLicense\n            )\n        {\n            ArgumentNullException.ThrowIfNull(publishLicense);\n\n            if (_fixedSettings)\n            {\n                throw new InvalidOperationException(SR.CannotChangePublishLicense);\n            }\n\n            // We seek to position 0 but under the covers, the VersionedStream maintains a FormatVersion\n            // structure before our logical position zero.\n            _publishLicenseStream.Seek(0, SeekOrigin.Begin);\n\n            //\n            // Construct a BinaryWriter to write the rest of the instance data.\n            //\n            // Although BinaryWriter is IDisposable, we must not Close or Dispose it,\n            // as that would close the underlying stream, which we do not own. Simply\n            // allowing the BinaryWriter to be finalized after it goes out of scope\n            // does -not- close the underlying stream.\n            //\n\n\n            // The stream is not owned by the BlockManager, therefore we cannot \n            // close the BinaryWriter, as that would Close the stream underneath.","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs#L180-L216","documentation":"SavePublishLicense throws InvalidOperationException with SR.CannotChangePublishLicense when the publish license is written after the transform's settings have been fixed (_fixedSettings == true). Once RM encryption settings are committed (e.g. after first use/flush), they are immutable for the lifetime of the transform. This protects the integrity of the encrypted compound file.","triggerScenarios":"Calling RightsManagementEncryptionTransform.SavePublishLicense after InitializeRMForCreate has completed and _fixedSettings was set to true; attempting to set a second publish license on the same transform instance.","commonSituations":"Reusing a cached RightsManagementEncryptionTransform instance across multiple protected documents; calling SavePublishLicense twice during package creation; retry logic that re-invokes initialization plus SavePublishLicense on a already-fixed transform.","solutions":["Create a new RightsManagementEncryptionTransform instance instead of reusing the fixed one","Call SavePublishLicense exactly once, before the settings are fixed","Check whether _fixedSettings-equivalent state (e.g. transform already initialized and flushed) before calling SavePublishLicense","Restructure code so the publish license is determined up front, prior to any encryption work"],"exampleFix":"// before\ntransform.SavePublishLicense(license1);\ntransform.SavePublishLicense(license2); // throws\n// after\ntransform.SavePublishLicense(license1);\nvar transform2 = new RightsManagementEncryptionTransform();\ntransform2.SavePublishLicense(license2);","handlingStrategy":"validation","validationCode":"if (transformIsFixed) throw new InvalidOperationException(\"Transform settings already fixed; create a new transform before calling SavePublishLicense\");","typeGuard":null,"tryCatchPattern":"try { transform.SavePublishLicense(license); } catch (InvalidOperationException ex) { /* recreate transform and retry once */ }","preventionTips":["Call SavePublishLicense exactly once per transform, immediately after initialization","Never reuse a RightsManagementEncryptionTransform across documents","Order initialization so the license is known before settings are fixed"],"tags":["wpf","rights-management","invalid-operation","state"],"backgroundTag":"invalid-state-transition","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"}