dotnet/wpf · error · ArgumentException
SR.IncorrectLocatorPartType
Error message
SR.IncorrectLocatorPartType ({locatorPart.PartType.Namespace}:{locatorPart.PartType.Name}) What it means
DataIdProcessor.ResolveLocatorPart only accepts locator parts whose PartType equals the processor's DataIdElementName. If the supplied ContentLocatorPart has any other PartType, it throws ArgumentException with SR.IncorrectLocatorPartType describing the offending type's namespace:name, naming the 'locatorPart' parameter. Each anchor processor handles exactly one locator-part type, so mismatched parts must be routed elsewhere.
Solutions
- Ensure the ContentLocatorPart is constructed with the exact PartType expected by DataIdProcessor (DataIdElementName) before calling ResolveLocatorPart.
- Look up the correct processor via AnnotationResource/locator part type matching instead of calling a fixed processor directly.
- If migrating old annotations, regenerate the locator part with the current DataId element type.
- Check locatorPart.PartType against the expected type first and skip/route to the appropriate processor when different.
Example fix
// before
processor.ResolveLocatorPart(wrongLocatorPart, node, out continueResolving);
// after
if (DataIdProcessor.DataIdElementName == wrongLocatorPart.PartType)
processor.ResolveLocatorPart(wrongLocatorPart, node, out continueResolving);
else
matchingProcessor.ResolveLocatorPart(wrongLocatorPart, node, out continueResolving); Defensive patterns
Strategy: type-guard
Validate before calling
if (locatorPart == null || !DataIdProcessor.DataIdElementName.Equals(locatorPart.PartType))
throw new InvalidOperationException("Locator part is not a DataId part; route to correct processor."); Type guard
static bool IsDataIdPart(ContentLocatorPart part) =>
part != null && part.PartType == DataIdProcessor.DataIdElementName; Try / catch
try { processor.ResolveLocatorPart(locatorPart, node, out var cont); }
catch (ArgumentException ex) when (ex.ParamName == "locatorPart") { RouteToMatchingProcessor(locatorPart, node); } Prevention
- Dispatch locator parts to processors by PartType match, not by fixed processor choice.
- When constructing ContentLocatorPart, source the PartType from the processor's expected element name.
- Validate locator parts during annotation deserialization/upgrade.
- Add an assertion that locator.PartType matches before adding to an anchor's ContentLocator.
When it happens
Trigger: Passing a ContentLocatorPart whose PartType is not DataIdProcessor's expected DataIdElementName into ResolveLocatorPart — e.g. feeding a PathProcessor/CharacterRangePart-type locator part to the DataId processor, or constructing a ContentLocatorPart with the wrong XName/type.
Common situations: Building annotation locators programmatically and mismatching processor types; deserializing annotation XML from another schema/version whose locator part type differs; iterating an anchor's locator parts in order and handing each to the wrong processor.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- InvalidEnumArgumentException("action", (int)action…
- InvalidEnumArgumentException("action", (int)action…
- SR.AnnotationAdorner_NotUIElement
- SR.AnnotationAlreadyExists
- SR.Format(SR.IncorrectLocatorPartType, " : ")
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/9dfeccb00395283e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Anchoring/DataIdProcessor.cs:181
/// </summary>
/// <param name="locatorPart">locator part to be matched, must be of the type
/// handled by this processor</param>
/// <param name="startNode">logical tree node to start search at</param>
/// <param name="continueResolving">return flag indicating whether the search
/// should continue (presumably because the search was not exhaustive)</param>
/// <returns>returns a node that matches the locator part; null if no such
/// node is found</returns>
/// <exception cref="ArgumentNullException">locatorPart or startNode are
/// null</exception>
/// <exception cref="ArgumentException">locatorPart is of the incorrect
/// type</exception>
public override DependencyObject ResolveLocatorPart(ContentLocatorPart locatorPart, DependencyObject startNode, out bool continueResolving)
{
ArgumentNullException.ThrowIfNull(locatorPart);
ArgumentNullException.ThrowIfNull(startNode);
if (DataIdElementName != locatorPart.PartType)
throw new ArgumentException(SR.Format(SR.IncorrectLocatorPartType, $"{locatorPart.PartType.Namespace}:{locatorPart.PartType.Name}"), nameof(locatorPart));
// Initial value
continueResolving = true;
// Get the values from the locator part...
string id = locatorPart.NameValuePairs[ValueAttributeName];
if (id == null)
{
throw new ArgumentException(SR.Format(SR.IncorrectLocatorPartType, $"{locatorPart.PartType.Namespace}:{locatorPart.PartType.Name}"), nameof(locatorPart));
}
// and from the node to examine.
string nodeId = GetNodeId(startNode);
if (nodeId != null)
{
if (nodeId.Equals(id))
{View on GitHub (pinned to 81131a70a4)