dotnet/wpf · error · ArgumentException
SR.InvalidAttachedAnchor
Error message
SR.InvalidAttachedAnchor
What it means
MarkedHighlightComponent.RegisterAnchor throws ArgumentException(SR.InvalidAttachedAnchor) when _attachedAnnotation.AttachedAnchor is not a TextAnchor. RegisterAnchor subscribes to caret/container events via anchor.Start.TextContainer, so only a TextAnchor (with a Start point) is usable; this runs as part of AddAttachedAnnotation.
Solutions
- Attach marked highlights only to text-backed content (FlowDocument/TextBox via AnnotationService) so anchors materialize as TextAnchor.
- Validate AttachedAnchor is TextAnchor before calling AddAttachedAnnotation.
- If reloading annotations, ensure the same AnnotationService/text container recreates the anchors before component registration.
Example fix
// before
markedHighlight.AddAttachedAnnotation(attachedAnnotation);
// after
if (!(attachedAnnotation.AttachedAnchor is TextAnchor))
return; // skip non-text anchors
markedHighlight.AddAttachedAnnotation(attachedAnnotation); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(_attachedAnnotation?.AttachedAnchor is TextAnchor)) return; // skip registration
Type guard
static bool IsTextAnchor(IAttachedAnnotation a) => a?.AttachedAnchor is TextAnchor;
Try / catch
try { component.AddAttachedAnnotation(a); } catch (ArgumentException) { /* non-text anchor; skip or log */ } Prevention
- Recreate TextAnchor locator parts on document load before attaching
- Only annotate text-backed content
- Reject foreign anchor formats at the store layer
When it happens
Trigger: AddAttachedAnnotation invoked with an annotation whose anchor came from a non-text locator part (e.g. a XPath/selector part) or is null; annotations synchronized from a store with foreign anchor formats.
Common situations: Custom AnnotationLocatorPart loaders that fail to recreate the TextAnchor on document reload; cross-document annotation moves; unit tests passing mock anchor objects.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.InvalidAttachedAnchor
- SR.AnnotationAdorner_NotUIElement
- SR.AnnotationIsNull
- SR.BadFixedTextPosition
- SR.Collection_BadType
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a31b3b483200b7b5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/MarkedHighlightComponent.cs:471
Children.Remove(_leftMarker);
if (_rightMarker != null)
Children.Remove(_rightMarker);
_leftMarker = null;
_rightMarker = null;
}
/// <summary>
/// Creates a HighlightComponent + 2 Path elements that mark the ends of the highlight.
/// Add everything to the Children.
/// Register for TextSelection.Changed and container parent GotFocus/LostFocus events
/// </summary>
private void RegisterAnchor()
{
//register for caret events
TextAnchor anchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
if (anchor == null)
{
throw new ArgumentException(SR.InvalidAttachedAnchor);
}
ITextContainer textContainer = anchor.Start.TextContainer;
Debug.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");
HighlightAnchor.AddAttachedAnnotation(_attachedAnnotation);
//this will set correct transformations on the markers
UpdateGeometry();
//host in the appropriate adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(AnnotatedElement); // note, GetAdornerLayer requires UIElement
if (layer == null) throw new InvalidOperationException(SR.Format(SR.NoPresentationContextForGivenElement, AnnotatedElement));
AdornerPresentationContext.HostComponent(layer, this, AnnotatedElement, false);
//register for selection changed
_selection = textContainer.TextSelection as ITextRange;View on GitHub (pinned to 81131a70a4)