dotnet/wpf · error · UnauthorizedAccessException
SR.StreamCannotBeWritten
Error message
SR.StreamCannotBeWritten
What it means
Flush() throws UnauthorizedAccessException (SR.StreamCannotBeWritten) when the underlying backing Stream is not writable. The store serializes pending annotations to this stream, so a read-only stream makes flushing impossible.
Solutions
- Open the stream with write access: new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite).
- Check stream.CanWrite before creating/flushing the store and surface a clear error to the user.
- Copy the annotation store to a writable location and reopen the store over that stream.
- Remove read-only attributes or fix share/ACL permissions on the store file.
Example fix
// before var stream = File.OpenRead(storePath); var store = new XmlStreamStore(stream); store.Flush(); // after var stream = File.Open(storePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); var store = new XmlStreamStore(stream); store.Flush();
Defensive patterns
Strategy: validation
Validate before calling
if (!stream.CanWrite) throw new InvalidOperationException("Annotation store stream is read-only; cannot flush."); Try / catch
try { store.Flush(); }
catch (UnauthorizedAccessException) { /* prompt user to save to a writable location */ } Prevention
- Open store streams with FileAccess.ReadWrite, never File.OpenRead.
- Check stream.CanWrite immediately after opening and before wiring up the store.
- Handle read-only media and locked-file scenarios (CD, network shares) with a save-as fallback.
When it happens
Trigger: Opening a stream with FileAccess.Read / FileMode.Open + read-only FileShare, or wrapping a write-protected file stream, then constructing XmlStreamStore over it and calling Flush() after annotations are marked dirty (or explicitly).
Common situations: Opening the annotation store file from a read-only location or medium (CD/DVD, read-only network share); opening the file while it is locked read-only; passing a MemoryStream that was created from a read-only buffer.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- SR.ReadNotSupported
- SR.UnauthorizedAccessExceptionWithFileName
- ArgumentOutOfRangeException(nameof(offset))
- can’t seek on baseStream
- Exception of type 'UnauthorizedAccessException' was thrown.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/eeb9ec65cc880880.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/Storage/XmlStreamStore.cs:363
/// <summary>
/// Causes any buffered data to be written to the underlying
/// storage mechanism. Gets called after each operation if
/// AutoFlush is set to true. The stream is truncated to
/// the length of the data written out by the store.
/// </summary>
/// <exception cref="UnauthorizedAccessException">stream cannot be written to</exception>
/// <exception cref="InvalidOperationException">if no stream has been set on the store</exception>
/// <exception cref="ObjectDisposedException">if object has been disposed</exception>
/// <seealso cref="AutoFlush"/>
public override void Flush()
{
lock (SyncRoot)
{
CheckStatus();
if (!_stream.CanWrite)
{
throw new UnauthorizedAccessException(SR.StreamCannotBeWritten);
}
if (_dirty)
{
SerializeAnnotations();
_stream.Position = 0;
_stream.SetLength(0);
_document.PreserveWhitespace = true;
_document.Save(_stream);
_stream.Flush();
_dirty = false;
}
}
}
/// <summary>
/// Returns a list of namespaces that are compatible with an input namespace
/// </summary>View on GitHub (pinned to 81131a70a4)