dotnet/wpf · error · ArgumentException
SR.InvalidAttachedAnnotation
Error message
SR.InvalidAttachedAnnotation
What it means
RemoveAttachedAnnotation only removes the exact IAttachedAnnotation instance this HighlightComponent currently holds. Passing any other instance throws ArgumentException with SR.InvalidAttachedAnnotation. The strict identity check keeps the component's range/highlight state consistent with what the manager believes is attached.
Solutions
- Keep the original IAttachedAnnotation reference returned at add time and pass that exact instance to RemoveAttachedAnnotation.
- Track the live attached annotation per component in your manager layer so removal uses identity, not an equal copy.
- Catch ArgumentException and log instead of failing when a best-effort cleanup is intended.
- Route removal through AnnotationService/AnnotationComponentManager rather than calling the component directly, so the right instance is resolved.
Example fix
// before
component.RemoveAttachedAnnotation(recreatedAnnotation); // identity mismatch -> throws
// after
if (ReferenceEquals(recreatedAnnotation, liveAnnotation))
component.RemoveAttachedAnnotation(liveAnnotation); Defensive patterns
Strategy: validation
Validate before calling
if (ReferenceEquals(attachedAnnotation, liveAttachedAnnotation))
component.RemoveAttachedAnnotation(liveAttachedAnnotation); Type guard
bool IsLive(IAttachedAnnotation a, IAttachedAnnotation live) => ReferenceEquals(a, live);
Try / catch
try { component.RemoveAttachedAnnotation(a); }
catch (ArgumentException) { /* not the live instance; resolve via the service */ } Prevention
- Keep the original instance reference from add time; never recreate for removal
- Remove via AnnotationService/manager, not raw component calls
- Avoid mixing annotation stores/services between add and remove
When it happens
Trigger: Calling RemoveAttachedAnnotation(attachedAnnotation) with an attachedAnnotation that is not reference-equal to the one previously added — e.g. a re-created IAttachedAnnotation from a reloaded annotation store.
Common situations: Rebuilding attached annotation objects between add and remove (store reload, clone); removing annotations against a different AnnotationService instance than the one that added them; holding serialized/deserialized attached annotations instead of the live instances.
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.InvalidGuid
- SR.MoreThanOneAttachedAnnotation
- anchorLocator.Parts
- Animation_ChildMustBeKeyFrame
- Animation_DependencyPropertyIsNotAnimatable
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/492ff266f3aaf6d5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/HighlightComponent.cs:267
highlightLayer.AddRange(this);
HighlightBrush = new SolidColorBrush(_background);
IsHitTestVisible = false;
//fire trace event
EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedHighlightEnd);
}
/// <summary>
/// Remove an attached annotation from the component
/// </summary>
/// <param name="attachedAnnotation">The attached annotation to be removed from the component</param>
public void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
{
ArgumentNullException.ThrowIfNull(attachedAnnotation);
if (attachedAnnotation != _attachedAnnotation)
{
throw new ArgumentException(SR.InvalidAttachedAnnotation, nameof(attachedAnnotation));
}
Invariant.Assert(_range != null, "null highlight range");
//fire trace event
EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedHighlightBegin);
//check input data and retrieve the TextContainer
ITextContainer textContainer = CheckInputData(attachedAnnotation);
Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");
//get AnnotationHighlightLayer in the textContainer
AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;
Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized");
//unregister of cargo changes
_attachedAnnotation.Annotation.CargoChanged -= new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);View on GitHub (pinned to 81131a70a4)