{"record":{"id":"218cec3f5ccf8b27","repo":"dotnet/wpf","slug":"sr-writenotsupported-versionedstreamowner","errorCode":null,"errorMessage":"SR.WriteNotSupported","messagePattern":"SR\\.WriteNotSupported","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs","lineNumber":340,"sourceCode":"        //------------------------------------------------------\n        //\n        //  Private Methods\n        //\n        //------------------------------------------------------\n        /// <summary>\n        /// Ensure that the version is persisted\n        /// </summary>\n        /// <remarks>Leaves stream at position just after the FormatVersion.\n        /// Destructive.  This is called automatically from WriteAttempt but callers\n        /// can call directly if they have changed the stream contents to a format\n        /// that is no longer compatible with the persisted FormatVersion.  If\n        /// this is not called directly, and a FormatVersion was found in the file\n        /// then only the Updater field is modified.\n        /// </remarks>\n        private void PersistVersion(FormatVersion version)\n        {\n            if (!BaseStream.CanWrite)\n                throw new NotSupportedException(SR.WriteNotSupported);\n\n            // normalize and save\n            long tempPos = checked(BaseStream.Position - _dataOffset);\n            BaseStream.Seek(0, SeekOrigin.Begin);\n\n            // update _dataOffset\n            long offset = version.SaveToStream(BaseStream);\n            _fileVersion = version;     // we know what it is - no need to deserialize\n\n            // existing value - ensure we didn't change sizes as this could lead to\n            // data corruption\n            if ((_dataOffset != 0) && (offset != _dataOffset))\n                throw new FileFormatException(SR.VersionUpdateFailure);\n\n            // at this point we know the offset\n            _dataOffset = offset;\n\n            // restore and shift","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs#L322-L358","documentation":"NotSupportedException (SR.WriteNotSupported) thrown by VersionedStreamOwner.PersistVersion when it needs to write/normalize the FormatVersion header but the underlying BaseStream is not writable (CanWrite == false). PersistVersion is invoked from WriteAttempt, so a write on a read-only versioned stream fails here first.","triggerScenarios":"Opening the compound file (or backing stream) with FileAccess.Read / read-only FileStream and then calling Write, WriteByte, or SetLength on the versioned stream — the first write triggers PersistVersion, which cannot write the version header.","commonSituations":"Files opened from read-only media or with read-only file attributes; streams opened FileAccess.Read out of caution then reused for updates; files under source control or opened from a zip/package exposed read-only.","solutions":["Open the backing stream with FileAccess.ReadWrite (or FileMode.OpenOrCreate) when updates are intended","Check BaseStream.CanWrite before attempting writes and surface a clear error or copy the file to a writable location first","Copy the read-only file to a temp location, update it there, and swap back on success","Remove the read-only attribute / fix permissions if the file is meant to be writable"],"exampleFix":"// before: read-only stream then write\nusing (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))\n{\n    var vs = new VersionedStreamOwner(fs, ...);\n    vs.Write(data, 0, data.Length); // NotSupportedException\n}\n// after: open for update when writes are needed\nusing (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))\n{\n    var vs = new VersionedStreamOwner(fs, ...);\n    vs.Write(data, 0, data.Length); // OK\n}","handlingStrategy":"validation","validationCode":"static void EnsureWritable(FileStream fs)\n{\n    if (!fs.CanWrite)\n        throw new InvalidOperationException(\"Stream was opened read-only; reopen with FileAccess.ReadWrite to update.\");\n}","typeGuard":"bool CanUpdate(VersionedStreamOwner owner) => owner?.BaseStream?.CanWrite == true;","tryCatchPattern":"try\n{\n    versionedStreamOwner.Write(data, 0, data.Length);\n}\ncatch (NotSupportedException)\n{\n    // reopen the backing file with write access (or copy to temp) and retry\n    using (var rw = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))\n    {\n        RetryWrite(rw, data);\n    }\n}","preventionTips":["Open with FileAccess.ReadWrite whenever updates are planned","Check File.Attributes for ReadOnly and clear it before opening for update","Never assume a stream is writable because the file is — verify CanWrite first","On read-only media, copy to a writable temp location before updating"],"tags":["read-only","write","stream","wpf"],"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"}