dotnet/wpf · error · InvalidOperationException
Image_OriginalStreamReadOnly
Error message
Image_OriginalStreamReadOnly
What it means
CreateInPlaceBitmapMetadataWriter requires the decoder's underlying source stream to be writable. CheckOriginalWritable throws InvalidOperationException with Image_OriginalStreamReadOnly when the original stream or file was opened read-only, so in-place metadata editing cannot proceed.
Solutions
- Open the backing file with FileAccess.ReadWrite / FileShare.Read so the decoder's _isOriginalWritable is true.
- Fall back to non-destructive editing: copy the frame through a BitmapFrame + BitmapMetadata into a new file.
- Check stream.CanWrite before calling CreateInPlaceBitmapMetadataWriter.
- Catch InvalidOperationException and save metadata via re-encoding instead.
Example fix
// before var fs = File.OpenRead(path); // read-only var dec = BitmapDecoder.Create(fs, opts, BitmapCacheOption.OnLoad); var writer = dec.CreateInPlaceBitmapMetadataWriter(); // throws // after using var fs = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); var dec = BitmapDecoder.Create(fs, opts, BitmapCacheOption.Default); var writer = dec.CreateInPlaceBitmapMetadataWriter();
Defensive patterns
Strategy: type-guard
Validate before calling
static bool CanEditInPlace(string path) =>
File.Exists(path) && new FileInfo(path).IsReadOnly == false; Type guard
bool DecoderSupportsInPlaceWrite(BitmapDecoder d) => d.Frames.Count > 0 && d.ToString() != null && d.InternalImagesCanBeWritten; // check CanWrite on the backing stream before calling
Try / catch
try { var writer = decoder.CreateInPlaceBitmapMetadataWriter(); writer.SetQuery("/app1/ifd/exif", metadata); }
catch (InvalidOperationException) { ReEncodeWithMetadata(decoder, outputPath, metadata); } Prevention
- Open files with FileAccess.ReadWrite when in-place metadata editing is planned
- Check stream.CanWrite before CreateInPlaceBitmapMetadataWriter
- Fall back to re-encode-and-save for read-only sources
- Copy resources out of embedded streams before editing
When it happens
Trigger: Calling decoder.CreateInPlaceBitmapMetadataWriter() when the decoder was built from a read-only FileStream, a URI with BitmapCreateOptions opened without write access, a MemoryStream that cannot be written, or a format that does not support in-place metadata updates.
Common situations: Editing EXIF/ICC metadata of images loaded from resources embedded in the assembly (read-only); files opened with FileAccess.Read; images on read-only media or without write permissions.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Cannot remove signature from read-only file.
- Image_EncoderNoGlobalMetadata
- SR.Format(SR.GridCollection_CannotModifyReadOnly…
- SR.Format(SR.ReadOnlyDesignerCoersionNotAllowed, Name)
- SR.Format(SR.ReadOnlyOverrideNotAllowed, Name)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/47dc3228740f7723.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/BitmapDecoder.cs:991
}
_isColorContextCached = true;
}
}
return _readOnlycolorContexts;
}
}
/// <summary>
/// Checks whether the underlying source is writable (useful for in-place metadata editing)
/// </summary>
internal void CheckOriginalWritable()
{
if (!_isOriginalWritable)
{
throw new System.InvalidOperationException(SR.Image_OriginalStreamReadOnly);
}
}
#endregion
#region Internal/Private Methods
internal static SafeMILHandle SetupDecoderFromUriOrStream(
Uri uri,
Stream stream,
BitmapCacheOption cacheOption,
out Guid clsId,
out bool isOriginalWritable,
out Stream uriStream,
out UnmanagedMemoryStream unmanagedMemoryStream,
out SafeFileHandle safeFilehandle
)
{View on GitHub (pinned to 81131a70a4)