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
- Disable the existing service (AnnotationService.GetService(root)?.Disable()) before enabling a new one.
- Reuse the existing service instance instead of constructing a new one.
- 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
- Cache and reuse one AnnotationService per viewer
- Always Disable before creating a new service on the same subtree
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
- SR.AnnotationServiceIsAlreadyEnabled
- SR.AnnotationServiceNotEnabled
- SR.Format(SR.ComponentAlreadyInPresentationContext…
- SR.Format(SR.ComponentNotInPresentationContext, component)
- SR.InvalidAttachedAnnotation
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 parametersView on GitHub (pinned to 81131a70a4)