dotnet/wpf · error · IOException

SR.PackagingCircularReference

Error message

SR.PackagingCircularReference

What it means

WriteableOnDemandStream.EnsureWritable rejects a writer stream that equals the on-demand stream itself (writer.Equals(this)); redirecting the active stream to itself would recurse forever. IOException(PackagingCircularReference) is thrown.

Solutions

  1. Make the factory return a fresh/independent underlying Stream, never the WriteableOnDemandStream instance itself.
  2. Review stream caching logic so cached streams are the raw storage streams, not the wrapper.
  3. Add a debug assert in the factory comparing the returned stream against the wrapper.

Example fix

// before
Stream Factory(FileMode m, FileAccess a) => this; // circular
// after
Stream Factory(FileMode m, FileAccess a) => _part.GetStream(m, a);
Defensive patterns

Strategy: validation

Validate before calling

Stream writer = CreateWriterStream();
if (ReferenceEquals(writer, onDemandStream))
    throw new InvalidOperationException("Factory returned the on-demand stream itself.");

Type guard

bool IsIndependent(Stream requested, Stream returned) => !ReferenceEquals(returned, requested);

Try / catch

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

Prevention

When it happens

Trigger: Write/SetLength on a WriteableOnDemandStream whose factory delegate returns the same stream instance it manages, instead of an independent underlying stream.

Common situations: Factory implementation that caches and returns 'this' or a stream that wraps nothing, typically a copy-paste bug in custom package part implementations.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

    {
        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
    //--------------------------------------------------------------------------
    // Private Fields
    //--------------------------------------------------------------------------

    /// <summary>
    /// The delegate we were given to have a writeable stream created.

View on GitHub (pinned to 81131a70a4)