dotnet/wpf · error · InvalidOperationException

Image_OnlyOneSave

Error message

Image_OnlyOneSave

What it means

BitmapEncoder.Save enforces that a bitmap container can be encoded exactly once; calling Save a second time on the same encoder throws InvalidOperationException(Image_OnlyOneSave). This is because the WIC encoding stream is consumed by the first save.

Solutions

  1. Call Save only once per BitmapEncoder instance
  2. Create a fresh encoder (and reopen the stream) for each save/retry
  3. Track _hasSaved-equivalent state in wrappers before calling Save
  4. Never mix manual encoder.Save with higher-level APIs that call Save internally

Example fix

// before
encoder.Save(stream);
encoder.Save(otherStream); // throws
// after
encoder.Save(stream);
var encoder2 = new PngBitmapEncoder();
encoder2.Frames.Add(BitmapFrame.Create(source));
encoder2.Save(otherStream);
Defensive patterns

Strategy: validation

Validate before calling

// caller-side: never call Save twice; guard with your own flag
if (!savedOnce) { encoder.Save(stream); savedOnce = true; }

Try / catch

try { encoder.Save(stream); }
catch (InvalidOperationException ex) when (IsOnlyOneSave(ex)) { log.Error("Encoder already saved; create a new encoder instance"); }

Prevention

When it happens

Trigger: Calling encoder.Save() twice on the same BitmapEncoder instance — directly, or indirectly when Save is invoked by GetBitmapImpl, CreateImagePart, CreateBrushImage, ReEncodeImage, or ConvertTo after an explicit Save already ran.

Common situations: Saving to a stream and then saving again to a file; defensive re-save in error handling; higher-level APIs (e.g. BitmapSource save paths) invoking Save internally after user code already did; retry loops that re-call Save instead of recreating the encoder.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/074cd7d6efd049aa. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/BitmapEncoder.cs:327

        /// <summary>
        /// Save (encode) the bitmap to the specified stream.
        /// </summary>
        /// <param name="stream">Stream to save into</param>
        public virtual void Save(System.IO.Stream stream)
        {
            VerifyAccess();
            EnsureBuiltIn();
            EnsureUnmanagedEncoder();

            // No-op to get rid of build error
            if (_encodeState == EncodeState.None)
            {
            }

            if (_hasSaved)
            {
                throw new InvalidOperationException(SR.Image_OnlyOneSave);
            }

            if (_frames == null)
            {
                throw new System.NotSupportedException(SR.Format(SR.Image_NoFrames, null));
            }

            int count = _frames.Count;
            if (count <= 0)
            {
                throw new System.NotSupportedException(SR.Format(SR.Image_NoFrames, null));
            }

            IntPtr comStream = IntPtr.Zero;
            SafeMILHandle encoderHandle = _encoderHandle;

            try
            {

View on GitHub (pinned to 81131a70a4)