dotnet/wpf · error · InvalidOperationException
The part name does not correspond to its content type.
Error message
The part name does not correspond to its content type.
What it means
DeobfuscatingStream wraps XPS obfuscated font streams (URI form 'pack://.../GUIDGUID/filename'). The stream URI passed to the constructor must resolve to a part URI with a valid part name; PackUriHelper.GetPartUri returned null because the URI does not identify a package part. This library throws InvalidOperationException because a content-type/part-name mismatch means the stream cannot be deobfuscated.
Solutions
- Verify the stream URI is an absolute pack URI pointing at a part (PackUriHelper.IsRelationshipPartUri / GetPartUri non-null) before constructing DeobfuscatingStream
- Ensure the part name follows the XPS obfuscated-font convention '/Resources/Fonts/GUIDGUID/fontname.odttf'
- Regenerate or re-embed the font part in the XPS package rather than renaming it manually
Example fix
// before
var stream = new DeobfuscatingStream(new Uri(fontPath, UriKind.RelativeOrAbsolute));
// after
var packUri = new Uri("pack://application:,,,/" + fontPath, UriKind.Absolute);
if (System.IO.Packaging.PackUriHelper.GetPartUri(packUri) == null)
throw new ArgumentException("Not a valid pack part URI", nameof(fontPath));
var stream = new DeobfuscatingStream(packUri); Defensive patterns
Strategy: validation
Validate before calling
if (uri == null || !uri.IsAbsoluteUri || System.IO.Packaging.PackUriHelper.GetPartUri(uri) == null)
throw new ArgumentException("streamUri must be an absolute pack URI identifying a package part", nameof(uri)); Type guard
static bool IsValidPackPartUri(Uri u) => u != null && u.IsAbsoluteUri && System.IO.Packaging.PackUriHelper.GetPartUri(u) != null;
Try / catch
try { var s = new DeobfuscatingStream(streamUri); ... } catch (InvalidOperationException ex) { log.Error("Invalid XPS font part name", ex); return null; } Prevention
- Always build font part URIs with PackUriHelper rather than string concatenation
- Verify XPS font part names follow the GUIDGUID/filename convention
- Validate URIs at package-authoring time, not just consumption time
When it happens
Trigger: Constructing DeobfuscatingStream with a Uri for which PackUriHelper.GetPartUri(streamUri) returns null — e.g. a URI without a 'pack://' scheme, missing the '/GUID-guid/path' obfuscated-font component, or otherwise not identifying a part inside a package.
Common situations: Loading an XPS document whose font part name is malformed or hand-edited; passing a relative or non-pack URI into the obfuscated-font pipeline; custom packaging code building font part URIs without the GUID prefix segment required by the XPS spec.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Document PackagePart URI is not valid.
- Cannot access the stream after it is closed.
- Only writers can call this method.
- Package must contain an XPS PackagePart.
- PackagePart already has associated Thumbnail.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/cd7b43de2e932124.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/DeobfuscatingStream.cs:203
/// <summary>
/// Constructor
/// </summary>
/// <param name="obfuscatedStream">stream that holds obfuscated resource</param>
/// <param name="streamUri">the original Uri which is used to obtain obfuscatedStream; it holds
/// the GUID information which is used to obfuscate the resources</param>
/// <param name="leaveOpen">if it is false, obfuscatedStream will be also disposed when
/// DeobfuscatingStream is disposed</param>
/// <remarks>streamUri has to be a pack Uri</remarks>
internal DeobfuscatingStream(Stream obfuscatedStream, Uri streamUri, bool leaveOpen)
{
ArgumentNullException.ThrowIfNull(obfuscatedStream);
// Make sure streamUri is in the correct form; getting partUri from it will do all necessary checks for error
// conditions; We also have to make sure that it has a part name
Uri partUri = System.IO.Packaging.PackUriHelper.GetPartUri(streamUri);
if (partUri == null)
{
throw new InvalidOperationException(SR.InvalidPartName);
}
// Normally we should use PackUriHelper.GetStringForPartUri to get the string representation of part Uri
// however, since we already made sure that streamUris is in the correct form (such as to check if it is an absolute Uri
// and there is a correct authority (package)), it doesn't have to be fully validated again.
// Get the escaped string for the part name as part names should have only ascii characters
String guid = Path.GetFileNameWithoutExtension(
streamUri.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped));
_guid = GetGuidByteArray(guid);
_obfuscatedStream = obfuscatedStream;
_ownObfuscatedStream = !leaveOpen;
}
#endregion
//------------------------------------------------------
//View on GitHub (pinned to 81131a70a4)