dotnet/wpf · error · ArgumentException
SR.StartNodeMustBeDocumentPageViewOrFixedPage
Error message
SR.StartNodeMustBeDocumentPageViewOrFixedPage
What it means
FixedTextSelectionProcessor.ResolveLocatorPart resolves a ContentLocatorPart into a TextAnchor for annotations on FixedDocument content. The method receives a DependencyObject 'startNode' that must be a DocumentPageView or FixedPage; otherwise it cannot anchor the text. This ArgumentException is thrown when the start node is neither of those types.
Solutions
- Pass the DocumentPageView (for FixedDocument) or FixedPage that actually hosts the annotated content as startNode.
- Verify the element type before calling: if (node is DocumentPageView || node is FixedPage) { ... }
- Ensure the annotations are targeting FixedDocument/DocumentSequence content, not Flow content (use TextSelectionProcessor for flow).
Example fix
// before
processor.ResolveLocatorPart(locatorPart, someVisual, out attachmentLevel);
// after
var pageView = VisualTreeHelperExt.FindDescendant<DocumentPageView>(someVisual);
processor.ResolveLocatorPart(locatorPart, pageView ?? throw new InvalidOperationException("No DocumentPageView in tree"), out attachmentLevel); Defensive patterns
Strategy: validation
Validate before calling
if (startNode is not DocumentPageView and not FixedPage) throw new InvalidOperationException("startNode must be DocumentPageView or FixedPage"); Type guard
bool IsValidStartNode(DependencyObject n) => n is DocumentPageView or FixedPage;
Try / catch
try { processor.ResolveLocatorPart(part, node, out var level); } catch (ArgumentException ex) { /* log: bad start node */ } Prevention
- Find the DocumentPageView via the visual tree before anchoring
- Match processor to content type (fixed vs flow)
- Never pass the service host control as startNode
When it happens
Trigger: Calling ResolveLocatorPart with a locator part whose start node (DependencyObject) is a null docPage — i.e. the passed startNode is not a DocumentPageView or FixedPage (or its subtree failed to resolve to one).
Common situations: Passing the wrong visual (e.g. the FlowDocumentPageView, a ScrollViewer, or the AnnotationService host control) instead of the DocumentPageView that hosts fixed content; custom anchoring code that walks the visual tree and grabs an ancestor of the page view.
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
- SR.AnnotationIsNull
- SR.Format(SR.NotHighlightAnnotationType…
- SR.IncorrectAnchorLength
- SR.InvalidAttachedAnchor
- SR.InvalidAttachedAnchor
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/92af99b6a275c8dd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Anchoring/FixedTextSelectionProcessor.cs:281
else
{
// If we were passed a DPV because we are walking the visual tree,
// extract the DocumentPage from it; its TextView will be used to
// turn coordinates into text positions
DocumentPageView dpv = startNode as DocumentPageView;
if (dpv != null)
{
docPage = dpv.DocumentPage as FixedDocumentPage;
if (docPage == null)
{
docPage = dpv.DocumentPage as FixedDocumentSequenceDocumentPage;
}
}
}
if (docPage == null)
{
throw new ArgumentException(SR.StartNodeMustBeDocumentPageViewOrFixedPage, nameof(startNode));
}
ArgumentNullException.ThrowIfNull(locatorPart);
attachmentLevel = AttachmentLevel.Unresolved;
ITextView tv = (ITextView)((IServiceProvider)docPage).GetService(typeof(ITextView));
Debug.Assert(tv != null);
ReadOnlyCollection<TextSegment> ts = tv.TextSegments;
//check first if a TextRange can be generated
if (ts == null || ts.Count <= 0)
return null;
TextAnchor resolvedAnchor = new TextAnchor();
if (docPage != null)View on GitHub (pinned to 81131a70a4)