dotnet/wpf · error · InvalidDataException

Document has more than one Thumbnail relationship.

Error message

Document has more than one Thumbnail relationship.

What it means

GetThumbnailPart enumerates the thumbnail relationships on the package/document and throws InvalidDataException (SR.ReachPackaging_MoreThanOneThumbnailPart) if more than one Thumbnail relationship is found. OPC/XPS permits only one thumbnail per package/document level, so duplicates make the package invalid for this API.

Solutions

  1. Open the package and delete the extra thumbnail relationships/parts (keep one, typically /Metadata/Thumbnail.jpeg).
  2. Fix the producer code to replace (not append) the thumbnail relationship when setting a new thumbnail.
  3. Re-save the document through the WPF XPS writer so relationships are normalized.
  4. Validate packages with an OPC validator before processing to catch duplicates upstream.

Example fix

// before
documentPart.CreateRelationship(thumbUri, TargetMode.Internal, thumbRelType); // may duplicate
// after
var existing = documentPart.GetRelationshipsByType(thumbRelType).ToList();
foreach (var rel in existing.Skip(0)) documentPart.DeleteRelationship(rel.Id);
documentPart.CreateRelationship(thumbUri, TargetMode.Internal, thumbRelType);
Defensive patterns

Strategy: validation

Validate before calling

int thumbCount = documentPart.GetRelationshipsByType(thumbnailRelationshipType).Count();
if (thumbCount > 1) throw new InvalidDataException("Package contains more than one Thumbnail relationship");

Type guard

bool HasSingleThumbnail(PackagePart p) => p.GetRelationshipsByType(thumbnailRelationshipType).Count() <= 1;

Try / catch

try { return xpsManager.GetThumbnailPart(); }
catch (InvalidDataException ex) when (ex.Message.Contains("Thumbnail")) { /* strip duplicate thumbnail relationships and retry once */ }

Prevention

When it happens

Trigger: Calling GetThumbnailPart on a package containing two or more relationships of the thumbnail relationship type, usually written by a non-conforming producer.

Common situations: Third-party XPS generators that add a thumbnail per document and also at package level incorrectly; merge tools concatenating packages and carrying over duplicate thumbnails; custom code re-adding a thumbnail without removing the previous relationship.

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/c43e1d34750bb8f8. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsManager.cs:651

            PackageRelationship thumbNailRel = null;
            PackagePart         thumbNailPart = null;
            PackageRelationshipCollection thumbnailCollection = null;
            if( parent != null )
            {
                thumbnailCollection = parent.
                    GetRelationshipsByType(XpsS0Markup.ThumbnailRelationshipName);
            }
            else
            {
                thumbnailCollection = _metroPackage.
                    GetRelationshipsByType(XpsS0Markup.ThumbnailRelationshipName);
            }

            foreach( PackageRelationship rel in thumbnailCollection )
            {
                if( thumbNailRel != null )
                {
                    throw new InvalidDataException(SR.ReachPackaging_MoreThanOneThumbnailPart);
                }
                thumbNailRel =  rel;
            }
            if (thumbNailRel != null)
            {
                thumbNailPart = _metroPackage.GetPart(PackUriHelper.ResolvePartUri(thumbNailRel.SourceUri, thumbNailRel.TargetUri));
            }
            return thumbNailPart;
        }

        public
        PackagePart
        GetPrintTicketPart(Uri documentUri)
        {
            PackagePart documentPart = _metroPackage.GetPart( documentUri );
            PackagePart printTicketPart = null;

            if( documentPart == null )

View on GitHub (pinned to 81131a70a4)