dotnet/wpf · error · InvalidOperationException

SR.AnnotationServiceAlreadyExists

Error message

SR.AnnotationServiceAlreadyExists

What it means

During Enable, VerifyServiceConfiguration checks that no other AnnotationService is attached at or above the given root via the ServiceProperty, and that none exists in the visual tree below. Finding one throws this InvalidOperationException because only one annotation service may govern a subtree.

Solutions

  1. Disable the existing service (AnnotationService.GetService(root)?.Disable()) before enabling a new one.
  2. Reuse the existing service instance instead of constructing a new one.
  3. Restructure so only one service covers the subtree; annotate sibling subtrees independently.

Example fix

// before
var s2 = new AnnotationService(viewer); s2.Enable(store); // service exists
// after
var existing = AnnotationService.GetService(viewer);
var service = existing ?? new AnnotationService(viewer);
if (existing == null) service.Enable(store);
Defensive patterns

Strategy: type-guard

Validate before calling

if (AnnotationService.GetService(root) != null) return; // a service already exists

Type guard

bool IsFree(DependencyObject root) => AnnotationService.GetService(root) == null;

Try / catch

try { service.Enable(store); } catch (InvalidOperationException) { /* reuse the existing service instead */ }

Prevention

When it happens

Trigger: Calling Enable() on a second AnnotationService whose root already has a service attached (its own or an ancestor's), or where any descendant element in the visual tree carries an AnnotationService.

Common situations: Nested viewers each with their own AnnotationService; re-enabling a new service on a viewer whose old service was never disabled; a parent FlowDocumentPageViewer already annotated when a child control's service is enabled.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

                        }
                    }
                    layer.Update(element);
                }
            }
        }

        /// <summary>
        /// Verify that no other annotation services are attached above, on or below root
        /// </summary>
        /// <param name="root">the proposed root for a new AnnotationService being enabled</param>
        /// <exception cref="InvalidOperationException">Other Instance of AnnotationService Is Already Set</exception>
        private static void VerifyServiceConfiguration(DependencyObject root)
        {
            Invariant.Assert(root != null, "Parameter 'root' is null.");

            // First make sure there isn't a service above us
            if (AnnotationService.GetService(root) != null)
                throw new InvalidOperationException(SR.AnnotationServiceAlreadyExists);

            // Now check the tree below us for an existing service
            DescendentsWalker<Object> walker = new DescendentsWalker<Object>(TreeWalkPriority.VisualTree, VerifyNoServiceOnNode, null);
            walker.StartWalk(root);
        }

        /// <summary>
        /// Finds the DocumentViewerBase object if root is DocumentViewerBase or FlowDocumentReader
        /// in paginated mode. If the root is FDSV or FDR in scroll mode - sets only the document;
        /// </summary>
        /// <param name="root">root the service is enabled on</param>
        /// <param name="documentViewerBase">DocumentViewerBase used by the viewer</param>
        /// <param name="document">document for the viewer</param>
        private static void GetViewerAndDocument(DependencyObject root, out DocumentViewerBase documentViewerBase, out IDocumentPaginatorSource document)
        {
            documentViewerBase = root as DocumentViewerBase;

            // Initialize out parameters

View on GitHub (pinned to 81131a70a4)