{"record":{"id":"789c29186ccbcc1c","repo":"dotnet/wpf","slug":"cannot-change-content-of-read-only-stream","errorCode":null,"errorMessage":"Cannot change content of read-only stream.","messagePattern":"Cannot change content of read-only stream\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/UnsafeIndexingFilterStream.cs","lineNumber":154,"sourceCode":"            \n            // The enum values of SeekOrigin match the STREAM_SEEK_* values. This\n            // convention is as good as carved in stone, so there's no need for a switch here.\n            _oleStream.Seek(offset, (int)origin, positionAddress);\n\n            return position;\n        }\n\n        /// <summary>\n        /// SetLength\n        /// </summary>\n        /// <exception cref=\"NotSupportedException\">not supported</exception>\n        /// <remarks>\n        /// Not supported. No indexing filter should require it.\n        /// </remarks>\n        public override void SetLength(long newLength)\n        {\n            ThrowIfStreamDisposed();\n            throw new NotSupportedException(SR.StreamDoesNotSupportWrite);\n        }\n\n        /// <summary>\n        /// Write\n        /// </summary>\n        /// <exception cref=\"NotSupportedException\">not supported</exception>\n        /// <remarks>\n        /// Not supported. No indexing filter should require it.\n        /// </remarks>\n        public override void Write(byte[] buf, int offset, int count)\n        {\n            ThrowIfStreamDisposed();\n            throw new NotSupportedException(SR.StreamDoesNotSupportWrite);\n        }\n\n        /// <summary>\n        /// Flush \n        /// </summary>","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/UnsafeIndexingFilterStream.cs#L136-L172","documentation":"UnsafeIndexingFilterStream represents the read-only content stream handed out by a COM indexing filter. SetLength is intentionally unsupported — no indexing filter requires resizing its content — so after a disposed check the method unconditionally throws NotSupportedException(SR.StreamDoesNotSupportWrite), whose text is \"Cannot change content of read-only stream.\"","triggerScenarios":"Calling SetLength on a stream obtained from an indexing filter (UnsafeIndexingFilterStream), or via code that generically resizes streams passed to it.","commonSituations":"Utility code that calls SetLength before writing (e.g. truncating a buffer-style stream) applied to a filter stream; Stream wrappers that unconditionally resize;CanWrite==false was ignored.","solutions":["Do not call SetLength on this stream; it is read-only by contract.","Check stream.CanWrite / this stream type before resizing and copy to a writable MemoryStream if mutation is needed.","If content must be modified, open the package part with PackagePart.GetStream(FileMode.Create, FileAccess.Write) instead of using the filter stream."],"exampleFix":"// before\nstream.SetLength(0);\nstream.Write(data, 0, data.Length);\n// after\nif (!stream.CanWrite)\n{\n    var writable = new MemoryStream();\n    stream.CopyTo(writable);\n    stream = writable; // mutate the copy instead\n}","handlingStrategy":"validation","validationCode":"if (stream is UnsafeIndexingFilterStream || !stream.CanWrite)\n    throw new InvalidOperationException(\"Stream is read-only; SetLength not allowed\");","typeGuard":"static bool IsWritable(Stream s) => s != null && s.CanWrite && !(s is System.IO.Packaging.UnsafeIndexingFilterStream);","tryCatchPattern":"try { stream.SetLength(newLength); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"read-only\"))\n{\n    // copy to a writable stream and resize there\n}","preventionTips":["Check CanWrite before calling SetLength or Write on any stream.","Never resize streams obtained from indexing filters.","Copy to MemoryStream or a PackagePart write stream when mutation is needed.","Centralize stream mutation behind helpers that assert writability."],"tags":["stream","read-only","unsupported-operation","packaging"],"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"}