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

  1. Attach marked highlights only to text-backed content (FlowDocument/TextBox via AnnotationService) so anchors materialize as TextAnchor.
  2. Validate AttachedAnchor is TextAnchor before calling AddAttachedAnnotation.
  3. 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

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


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)