dotnet/wpf · error · InvalidOperationException

SR.InvalidAnchorPosition

Error message

SR.InvalidAnchorPosition

What it means

StickyNoteControl.GetDesiredTransform (IAnnotationComponent) computes a transform from the attached annotation's AnchorPoint; if the anchor coordinates are infinite (non-finite layout result), the transform cannot be computed and it throws InvalidOperationException('InvalidAnchorPosition'). Anchor points of NaN are tolerated (returns null, no transform) but Infinity is treated as a layout failure.

Solutions

  1. Verify/repair the annotation's anchor data in the annotation store; delete and recreate the annotation if the anchor is corrupt.
  2. Ensure the annotation's anchor components are resolved to finite rectangles before StickyNote renders (force layout / refresh AnnotationService).
  3. Guard rendering code: remove or skip annotations whose AnchorPoint is non-finite before adding them to the service.
  4. Catch InvalidOperationException during annotation rendering and fall back to re-creating the annotation.

Example fix

// before
component.GetDesiredTransform(anchor); // throws on Infinity
// after
if (!double.IsInfinity(anchor.AnchorPoint.X) && !double.IsInfinity(anchor.AnchorPoint.Y))
    component.GetDesiredTransform(anchor);
Defensive patterns

Strategy: validation

Validate before calling

bool anchorValid = !double.IsInfinity(attachedAnnotation.AnchorPoint.X) && !double.IsInfinity(attachedAnnotation.AnchorPoint.Y);

Type guard

static bool HasFiniteAnchor(IAttachedAnnotation aa) =>
    aa != null && !double.IsInfinity(aa.AnchorPoint.X) && !double.IsInfinity(aa.AnchorPoint.Y);

Try / catch

try { var t = component.GetDesiredTransform(target); }
catch (InvalidOperationException) { /* recreate annotation: anchor is corrupt */ }

Prevention

When it happens

Trigger: An IAttachedAnnotation whose AnchorPoint is double.PositiveInfinity or double.NegativeInfinity in either coordinate during transform computation, typically produced by degenerate anchors from broken document layout or anchor segments resolving to empty rectangles.

Common situations: Annotations attached to content whose anchor was invalidated by scrolling/pagination, annotation files edited externally with bogus anchor points, rendering annotations while layout has not produced finite positions.

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/f9765b0872174496. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/StickyNote/StickyNoteAnnotations.cs:1008

                // we need to mirror ourselves.  This is work around an issue with DocumentViewerBase which mirrors its
                // contents (because its generated always as LeftToRight).  We are anchored to that content so the mirror
                // gets applied to as as well.  This is our attempt to cancel out that mirror.
                if (this.IsExpanded
                    && this.FlowDirection == FlowDirection.RightToLeft
                    && _attachedAnnotation.Parent is DocumentPageHost)
                {
                    _selfMirroring = true;
                }
                else
                {
                    _selfMirroring = false;
                }

                Point anchor = _attachedAnnotation.AnchorPoint;

                if (double.IsInfinity(anchor.X) || double.IsInfinity(anchor.Y))
                {
                    throw new InvalidOperationException(SR.InvalidAnchorPosition);
                }

                if ((double.IsNaN(anchor.X)) || (double.IsNaN(anchor.Y)))
                    return null;

                GeneralTransformGroup transformations = new GeneralTransformGroup();

                // We should be in normal Right-To-Left mode, but because of special cases
                // in DocumentPageView, we've been mirrored.  We detect this and re-mirror
                // ourselves.  We also need to do special handling of move/resize operations.
                if (_selfMirroring)
                {
                    // This is the mirroring transform that will get the StickyNote to lay out
                    // as if it were in Right-To-Left mode
                    transformations.Children.Add(new MatrixTransform(-1.0, 0.0, 0.0, 1.0, this.Width, 0.0));
                }

                transformations.Children.Add(new TranslateTransform(anchor.X, anchor.Y));

View on GitHub (pinned to 81131a70a4)