dotnet/wpf · error · ArgumentException

SR.ParameterMustBeLogicalNode

Error message

SR.ParameterMustBeLogicalNode

What it means

The internal AnnotationService(DependencyObject) constructor throws ArgumentException when the root is neither a FrameworkElement nor a FrameworkContentElement. The annotation service attaches to the logical tree, so the root must be a logical node that can host annotation attached properties and resolve IServiceProvider. Public entry points like AnnotationService.Enable/Disable call this with the viewer, so passing an arbitrary DependencyObject fails.

Solutions

  1. Pass a supported viewer such as DocumentViewer, FlowDocumentPageViewer, FlowDocumentScrollViewer, or FlowDocumentReader as the root.
  2. Ensure the DependencyObject is a FrameworkElement or FrameworkContentElement before constructing/enabling the service.
  3. Use the public AnnotationService.Enable(service, viewer) path with a supported DocumentViewerBase/FlowDocumentScrollViewer.
  4. If annotating custom content, wrap it in a supported viewer rather than passing the raw object.

Example fix

// before
var service = new AnnotationService(myVisual as DependencyObject);

// after
if (myVisual is FrameworkElement fe)
{
    var service = new AnnotationService(fe);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(root is FrameworkElement) && !(root is FrameworkContentElement))
    throw new ArgumentException("root must be a logical tree node");

Type guard

bool CanHostAnnotationService(DependencyObject o) =>
    o is FrameworkElement or FrameworkContentElement;

Try / catch

try { var service = new AnnotationService(root); service.Enable(store); }
catch (ArgumentException) { /* use a supported viewer host instead */ }

Prevention

When it happens

Trigger: Constructing an AnnotationService with a DependencyObject that is not part of a logical tree — e.g. a DispatcherObject, an AnimationClock, a raw Visual that is not a FrameworkElement, or a FrameworkContentElement-less content node.

Common situations: Attempting to enable annotations on unsupported hosts (custom viewers, ItemsControl items, free visuals); passing a DependencyObject from reflection or generic plumbing code; wiring annotations to non-WPF-framework objects.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/AnnotationService.cs:134

            ArgumentNullException.ThrowIfNull(viewer);

            Initialize(viewer);
        }


        /// <summary>
        ///     Creates an instance of the AnnotationService focused on a particular
        ///     tree node.
        /// </summary>
        /// <param name="root">the tree node this service will operate on</param>
        /// <exception cref="ArgumentNullException">root is null</exception>
        /// <exception cref="ArgumentException">element is not a FrameworkElement or FrameworkContentElement</exception>
        internal AnnotationService(DependencyObject root)
        {
            ArgumentNullException.ThrowIfNull(root);

            if (!(root is FrameworkElement || root is FrameworkContentElement))
                throw new ArgumentException(SR.ParameterMustBeLogicalNode, nameof(root));

            Initialize(root);
        }

        #endregion Constructors

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        #region Public Methods

        /// <summary>
        ///     Enables the service with the given store.
        /// </summary>
        /// <param name="annotationStore">store to use for retreiving and persisting annotations</param>

View on GitHub (pinned to 81131a70a4)