dotnet/wpf · error · ArgumentException

SR.MoreThanOneAttachedAnnotation

Error message

SR.MoreThanOneAttachedAnnotation

What it means

HighlightComponent supports at most one attached annotation at a time: it keeps a single _attachedAnnotation/_range pair for the highlight. AddAttachedAnnotation throws ArgumentException with SR.MoreThanOneAttachedAnnotation when a second attached annotation is added while one is still held.

Solutions

  1. Call RemoveAttachedAnnotation for the existing attached annotation before adding a new one.
  2. Deduplicate annotation resources before applying so the same component never receives two annotations.
  3. Catch ArgumentException to detect duplicates and skip/merge instead of adding.
  4. Inspect the component's current attached annotation (if exposed) and choose modify/update logic rather than add.

Example fix

// before
component.AddAttachedAnnotation(attachedAnnotation); // throws if one exists
// after
if (component.HasAttachedAnnotation)
    component.RemoveAttachedAnnotation(component.CurrentAttachedAnnotation);
component.AddAttachedAnnotation(attachedAnnotation);
Defensive patterns

Strategy: validation

Validate before calling

if (component.CurrentAttachedAnnotation != null)
    component.RemoveAttachedAnnotation(component.CurrentAttachedAnnotation);
component.AddAttachedAnnotation(attachedAnnotation);

Type guard

bool CanAdd(IAnnotationComponent c) => c is HighlightComponent hc && !hc.HasAttachedAnnotation;

Try / catch

try { component.AddAttachedAnnotation(a); }
catch (ArgumentException) { /* duplicate: already has an attached annotation */ }

Prevention

When it happens

Trigger: Calling AddAttachedAnnotation on a HighlightComponent (directly or via AnnotationComponentManager.AddToAttachedAnnotations) when _attachedAnnotation is already non-null — i.e. the previous attached annotation was not removed first.

Common situations: Applying the same annotation resource twice to overlapping ranges resolved to the same component; annotation store re-delivery/duplicate resolution during service reload; failing to call RemoveAttachedAnnotation during teardown before re-adding.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/e1b1840bd55c5377. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/HighlightComponent.cs:217

        /// The HighlightComponent uses built-in highlight rendering, so no transformation is needed
        /// </summary>
        /// <param name="transform">Transform to the AnnotatedElement.</param>
        /// <returns>Transform to the annotation component</returns>
        public GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            return transform;
        }

        /// <summary>
        /// Add an attached annotation to the component. The attached anchor will be used to add
        /// a highlight to the appropriate TextContainer
        /// </summary>
        /// <param name="attachedAnnotation">The attached annotation to be added to the component</param>
        public void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (_attachedAnnotation != null)
            {
                throw new ArgumentException(SR.MoreThanOneAttachedAnnotation);
            }

            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedHighlightBegin);

            //check input data and retrieve the TextContainer
            ITextContainer textContainer = CheckInputData(attachedAnnotation);

            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;

            //Get highlight Colors from the cargo. For undefined Colors the default values are used
            GetColors(attachedAnnotation.Annotation, out _background, out _selectedBackground);
            _range = textAnchor;

            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");

            //get or create AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;

View on GitHub (pinned to 81131a70a4)