dotnet/wpf · error · ArgumentException

SR.Image_StreamWrite

Error message

SR.Image_StreamWrite

What it means

StrokeCollection.Save(Stream, bool) writes the collection as ISF to the given stream. It requires stream.CanWrite; a non-writable stream causes ArgumentException(SR.Image_StreamWrite). The stream must be writable for ISF serialization to proceed.

Solutions

  1. Open the destination with write access (FileMode.Create, FileAccess.Write) before calling Save
  2. Check stream.CanWrite in the caller and re-open a writable stream if false
  3. Wrap the destination in a MemoryStream if the ultimate target is read-only, then copy it out

Example fix

// before
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
strokes.Save(fs, true);
// after
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
strokes.Save(fs, true);
Defensive patterns

Strategy: validation

Validate before calling

bool writable = stream is not null && stream.CanWrite;

Type guard

static bool IsWritableStream(Stream? s) => s is not null && s.CanWrite;

Try / catch

try { strokes.Save(stream, compress: true); } catch (ArgumentException ex) when (ex.ParamName == "stream") { /* open a writable stream and retry */ }

Prevention

When it happens

Trigger: Calling Save on a stream opened with FileAccess.Read, a read-only FileStream, or a closed/disposed stream.

Common situations: Saving ink to a file opened read-only by mistake; writing to a stream retrieved from a read-only resource; passing an input stream variable where an output stream was intended.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs:84

                throw new ArgumentException(SR.Invalid_isfData_Length, nameof(stream));
            }

            //this will init our stroke collection
            StrokeCollectionSerializer serializer = new StrokeCollectionSerializer(this);
            serializer.DecodeISF(seekableStream);
        }


        /// <summary>Save the collection of strokes, including any custom attributes to a stream</summary>
        /// <param name="stream">The stream to save Ink Serialized Format to</param>
        /// <param name="compress">Flag if set to true the data will be compressed, which can
        /// reduce the output buffer size in exchange for slower Save performance.</param>
        public virtual void Save(Stream stream, bool compress)
        {
            ArgumentNullException.ThrowIfNull(stream);
            if ( !stream.CanWrite )
            {
                throw new ArgumentException(SR.Image_StreamWrite, nameof(stream));
            }
            SaveIsf(stream, compress);
        }

        /// <summary>Save the collection of strokes uncompressed, including any custom attributes to a stream</summary>
        /// <param name="stream">The stream to save Ink Serialized Format to</param>
        public void Save(Stream stream)
        {
            Save(stream, true);
        }

        /// <summary>
        /// Internal method for getting just the byte[] out
        /// </summary>
        internal void SaveIsf(Stream stream, bool compress)
        {
            StrokeCollectionSerializer serializer = new StrokeCollectionSerializer(this)
            {

View on GitHub (pinned to 81131a70a4)