dotnet/wpf · error · NotSupportedException

SR.PackagePartTypeNotWritable

Error message

SR.PackagePartTypeNotWritable

What it means

RestrictedTransactionalPackage.MergeChanges scans every part of the temporary package and refuses to merge if any part has a content type not on the allow-list (IsValidContentType). It throws NotSupportedException(SR.PackagePartTypeNotWritable) because a restricted package may only modify permitted part types.

Solutions

  1. Only add parts whose ContentType passes IsValidContentType before merging
  2. Inspect TempPackage.GetParts() and remove or convert disallowed parts before MergeChanges
  3. Catch NotSupportedException around MergeChanges and report which content type was rejected

Example fix

// before
package.MergeChanges(target);
// after
foreach (var part in tempPackage.GetParts())
    if (!IsValidContentType(part.ContentType))
        throw new InvalidOperationException("Unsupported part: " + part.ContentType);
package.MergeChanges(target);
Defensive patterns

Strategy: validation

Validate before calling

bool mergeable = tempPackage.GetParts().All(p => p == null || IsValidContentType(p.ContentType)); if (!mergeable) { /* clean up or abort */ }

Try / catch

try { package.MergeChanges(target); } catch (NotSupportedException ex) { /* report disallowed content type */ }

Prevention

When it happens

Trigger: Calling MergeChanges when the temp package contains a part with a disallowed ContentType (e.g., a content type outside the fixed-document whitelist).

Common situations: Editing an XPS document and adding non-XPS parts (images/media with unexpected content types); plugins or code inserting arbitrary parts into the temp package.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationUI/MS/Internal/Documents/Application/RestrictedTransactionalPackage.cs:54

    internal RestrictedTransactionalPackage(Stream original)
        : base(original)
    { }
    #endregion Constructors

    /// <exception cref="System.ArgumentNullException" />
    /// <exception cref="System.ArgumentException" />
    internal override void MergeChanges(Stream target)
    {
        ArgumentNullException.ThrowIfNull(target);

        if (TempPackage != null)
        {
            foreach (PackagePart part in TempPackage.GetParts())
            {
                // Ensure that all parts being modified are permitted.
                if ((part != null) && (!IsValidContentType(part.ContentType)))
                {
                    throw new NotSupportedException(SR.PackagePartTypeNotWritable);
                }
            }

            base.MergeChanges(target);
        }
    }

    /// <summary>
    /// Creates a new PackagePart.
    /// </summary>
    /// <remarks>
    /// When creating a new PackagePart we must:
    ///    a) ensure the part does not exist in package
    ///    b) ensure there is a writable package
    ///    c) create a temp part
    ///    d) update active part reference to the temp part
    /// 
    /// What if a PackagePart with the same Uri already exists?

View on GitHub (pinned to 81131a70a4)