dotnet/wpf · error · ArgumentException
SR.NotAValidRelationshipPartUri
Error message
SR.NotAValidRelationshipPartUri
What it means
ArgumentException with message SR.NotAValidRelationshipPartUri thrown by PackUriHelper.IsRelationshipUri. A pack URI whose part name ends in '.rels' and also contains an upper-case '_rels' segment as the third-last segment is not a valid relationship part name, because '_rels' segments may only appear immediately before the '/xxx.rels' leaf.
Solutions
- Build part URIs with PackUriHelper.CreatePartUri instead of manual strings.
- Fix the URI so '_rels' appears only as the segment immediately preceding the '.rels' leaf.
- Validate the URI with PackUriHelper.IsRelationshipPartUri / ValidatedPartUri before use.
- Repair or regenerate the offending package with the Open XML SDK or a known-good producer.
Example fix
// before
var uri = new Uri("/word/_rels/document/_rels/document.xml.rels", UriKind.Relative);
// after
var partUri = PackUriHelper.CreatePartUri(new Uri("/word/document.xml", UriKind.Relative));
var relsUri = PackUriHelper.GetRelationshipPartUri(partUri); // /word/_rels/document.xml.rels Defensive patterns
Strategy: validation
Validate before calling
bool IsValidRelsUri(Uri u) => !u.ToString().Contains("_rels/") || PackUriHelper.IsRelationshipPartUri(u); Try / catch
try { partUri = PackUriHelper.ValidatedPartUri(uri); }
catch (ArgumentException) { /* log malformed pack URI, reject package */ } Prevention
- Use PackUriHelper.CreatePartUri for all part URIs
- Never hand-concatenate '_rels' segments
- Sanitize third-party package part names on import
When it happens
Trigger: Calling PackUriHelper.ValidatedPartUri (or CreatePartUri/GetRelationshipPartUri) with a pack URI like '/a/_rels/b/_rels/c.rels' — i.e., a .rels part nested under another _rels folder, or upper-case _rels segments misplaced in the path.
Common situations: Constructing part URIs by string concatenation instead of PackUriHelper APIs; OPC packages produced by non-.NET tools with malformed '_rels' placement; migrating packages between formats that lowercase/uppercase segment names.
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
- Resource_XpsPackageBoundaryViolation
- SR.FamilyMap_TargetNotSet
- SR.XpsValidatingLoaderUriNotInSamePackage
- ' ' is not a valid value for this control.
- Argument 'propertyName' cannot be null or empty.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f4eac774c250a65d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackUriHelper.cs:511
// must be at least two segments and the last one must end with .RELs
// and the length of the segment should be greater than just the extension.
if ((segments.Length >= 3) &&
(segments[segments.Length - 1].Length > _relationshipPartExtensionName.Length))
{
// look for "_RELS" segment which must be second last segment
result = string.Equals(segments[segments.Length - 2], _relationshipPartUpperCaseSegmentName, StringComparison.Ordinal);
}
// In addition we need to make sure that the relationship is not created by taking another relationship
// as the source of this uri. So XXX/_rels/_rels/YYY.rels.rels would be invalid.
if (segments.Length > 3 && result)
{
if ((segments[segments.Length - 1]).EndsWith(_relsrelsUpperCaseExtension, StringComparison.Ordinal))
{
// look for "_rels" segment in the third last segment
if(string.Equals(segments[segments.Length - 3], _relationshipPartUpperCaseSegmentName, StringComparison.Ordinal))
throw new ArgumentException(SR.NotAValidRelationshipPartUri);
}
}
return result;
}
//Returns the normalized string for the part uri.
//Currently normalizing the PartUriString consists of only one step -
//1. Take the wellformed and escaped partUri string and case fold to UpperInvariant
private string GetNormalizedPartUriString()
{
//Case Fold the partUri string to Invariant Upper case (this helps us perform case insensitive comparison)
//We follow the Simple case folding specified in the Unicode standard
if (_isNormalized)
return _partUriString;
else
return _partUriString.ToUpperInvariant();View on GitHub (pinned to 81131a70a4)