dotnet/wpf · error · InvalidOperationException

SR.NoAttachedAnnotationToModify

Error message

SR.NoAttachedAnnotationToModify

What it means

HighlightComponent.Activate toggles the active/inactive highlight color, which requires an attached annotation to color. If the component holds no attached annotation (_attachedAnnotation == null), it throws InvalidOperationException with SR.NoAttachedAnnotationToModify. Activating an empty highlight is meaningless, so the framework refuses it.

Solutions

  1. Only call Activate when the component has an attached annotation; check your manager's state first.
  2. Catch InvalidOperationException and treat it as a no-op when activation is best-effort (e.g. focus painting).
  3. Reorder teardown so activation handlers unsubscribe before RemoveAttachedAnnotation runs.
  4. Re-add the attached annotation before activating if the annotation should still be present.

Example fix

// before
component.Activate(true); // throws when annotation already removed
// after
try { component.Activate(true); }
catch (InvalidOperationException) { /* no attached annotation; nothing to highlight */ }
Defensive patterns

Strategy: validation

Validate before calling

bool canActivate = component.HasAttachedAnnotation;
if (canActivate) component.Activate(true);

Type guard

bool CanActivate(HighlightComponent hc) => hc.HasAttachedAnnotation;

Try / catch

try { component.Activate(active); }
catch (InvalidOperationException) { /* no attached annotation; skip activation */ }

Prevention

When it happens

Trigger: Calling Activate(true/false) on a HighlightComponent before AddAttachedAnnotation, or after RemoveAttachedAnnotation cleared the component (e.g. during focus/selection change handlers when the annotation was already detached).

Common situations: Focus/selection UI calling Activate on highlight components whose annotations were just removed by store updates; activation logic running after AnnotationService disabled annotations and cleared components; race between activation handler and annotation reload.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

        public void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
        {
            throw new NotSupportedException(SR.NotSupported);
        }

        /// <summary>
        /// Sets highlight color to active/inactive
        /// <param name="active">true - activate, false = deactivate</param>
        /// </summary>
        public void Activate(bool active)
        {
            //return if the state is unchanged
            if (_active == active)
                return;

            //get the highlight layer
            if (_attachedAnnotation == null)
            {
                throw new InvalidOperationException(SR.NoAttachedAnnotationToModify);
            }

            TextAnchor textAnchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
            Invariant.Assert(textAnchor != null, "AttachedAnchor is not a text anchor");

            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer;
            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized");

            highlightLayer.ActivateRange(this, active);
            _active = active;

            if (active)
                HighlightBrush = new SolidColorBrush(_selectedBackground);

View on GitHub (pinned to 81131a70a4)