dotnet/wpf · error · IOException

SR.PackagingWriteableDelegateGaveNullStream

Error message

SR.PackagingWriteableDelegateGaveNullStream

What it means

WriteableOnDemandStream.EnsureWritable invokes the _writeableStreamFactory delegate to obtain the real writeable stream; if the delegate returns null the lazy stream has no backing writer, so IOException(PackagingWriteableDelegateGaveNullStream) is thrown.

Solutions

  1. Ensure the writeable stream factory always returns a non-null Stream or throws an exception with context.
  2. Check that the package/part backing the stream is still open and writeable when the factory executes.
  3. Validate writeability (part-level checks) before beginning the deferred write flow.

Example fix

// before
Stream Factory(FileMode m, FileAccess a) => _part?.GetStream(m, a); // null when _part is null
// after
Stream Factory(FileMode m, FileAccess a)
{
    if (_part == null) throw new IOException("Backing part unavailable for write");
    return _part.GetStream(m, a);
}
Defensive patterns

Strategy: validation

Validate before calling

if (backingPart == null || !backingPart.FileOpenAccess.HasFlag(FileAccess.Write))
    throw new IOException("Backing part unavailable or not writeable for on-demand stream.");

Type guard

bool CanProvideWritableStream(Func<FileMode, FileAccess, Stream> f)
{ try { return f?.Invoke(FileMode.OpenOrCreate, FileAccess.Write) != null; } catch { return false; } }

Try / catch

try { stream.Write(data, 0, data.Length); }
catch (IOException ex) when (ex.Message.Contains("GaveNullStream"))
{ Log.Error("Stream factory returned null", ex); }

Prevention

When it happens

Trigger: First Write or SetLength call on an on-demand stream that is not yet actively writeable, where the registered WriteableStreamFactory callback returns null instead of a Stream.

Common situations: Deferred-save XPS scenarios where the factory's part creation failed silently (package disposed, part missing) and the error path returned null rather than throwing.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/WriteableOnDemandStream.cs:287

    /// Ensures either the active stream is our writeable stream or uses the
    /// factory delegate to get one and assign it as the active stream.
    /// </summary>
    /// <exception cref="System.IO.IOException" />
    /// <exception cref="System.NotSupportedException" />
    private void EnsureWritable()
    {
        if (!_wantedWrite)
        {
            throw new NotSupportedException(
                SR.PackagingWriteNotSupported);
        }

        if (!_isActiveWriteable)
        {
            Stream writer = _writeableStreamFactory(_mode, _access);
            if (writer == null)
            {
                throw new IOException(
                    SR.PackagingWriteableDelegateGaveNullStream);
            }

            if (writer.Equals(this))
            {
                throw new IOException(
                    SR.PackagingCircularReference);
            }

            writer.Position = _active.Position;

            _active = writer;
            _isActiveWriteable = true;
        }
    }
    #endregion Private Methods

    #region Private Fields

View on GitHub (pinned to 81131a70a4)