dotnet/wpf · error · InvalidOperationException

SR.AnnotationServiceIsAlreadyEnabled

Error message

SR.AnnotationServiceIsAlreadyEnabled

What it means

AnnotationService.Enable throws InvalidOperationException when Enable is called on a service instance that is already enabled (_isEnabled is true). Each AnnotationService can be enabled exactly once until Disable is called; re-enabling the live instance is an invalid state transition. This follows VerifyAccess, so it only occurs on the dispatcher thread.

Solutions

  1. Check service.IsEnabled before calling Enable and skip if already true.
  2. Call service.Disable() before re-enabling with a different store.
  3. Guard initialization with a flag so overlapping Loaded/navigation events cannot enable twice.
  4. Create a fresh AnnotationService instance (disabling the old one first) if a new store is required.

Example fix

// before
service.Enable(store); // may run again on re-Load

// after
if (!service.IsEnabled)
    service.Enable(store);
Defensive patterns

Strategy: validation

Validate before calling

if (!service.IsEnabled)
    service.Enable(store);

Type guard

bool CanEnable(AnnotationService s) => s != null && !s.IsEnabled;

Try / catch

try { service.Enable(store); }
catch (InvalidOperationException) { /* already enabled — no-op */ }

Prevention

When it happens

Trigger: Calling service.Enable(store) twice on the same AnnotationService instance without an intervening Disable(), e.g. Enable invoked from both a Loaded event and a navigation handler, or re-Enable after the viewer re-loads while the service stayed enabled.

Common situations: Double initialization from overlapping UI events (Loaded firing multiple times, tab re-activation); application startup code running twice; forgetting that Enable on a new store requires Disable first; MVVM re-attach logic enabling an already-enabled service.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

        #region Public Methods

        /// <summary>
        ///     Enables the service with the given store.
        /// </summary>
        /// <param name="annotationStore">store to use for retreiving and persisting annotations</param>
        /// <exception cref="ArgumentNullException">store is null</exception>
        /// <exception cref="InvalidOperationException">DocumentViewerBase has content which is neither
        /// FlowDocument or FixedDocument; only those two are supported</exception>
        /// <exception cref="InvalidOperationException">this service or another service is already
        /// enabled for the DocumentViewerBase</exception>
        public void Enable(AnnotationStore annotationStore)
        {
            ArgumentNullException.ThrowIfNull(annotationStore);

            VerifyAccess();

            if (_isEnabled)
                throw new InvalidOperationException(SR.AnnotationServiceIsAlreadyEnabled);

            // Make sure there isn't a service above or below us
            VerifyServiceConfiguration(_root);

            // Post a background work item to load existing annotations.  Do this early in the
            // Enable method in case any later code causes an indirect call to LoadAnnotations,
            // this cached operation will make that LoadAnnotations call a no-op.
            _asyncLoadOperation = _root.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(LoadAnnotationsAsync), this);

            // Enable the store and set it on the tree
            _isEnabled = true;
            _root.SetValue(AnnotationService.ServiceProperty, this);
            _store = annotationStore;

            // If our root is a DocumentViewerBase we need to setup some special processors.
            DocumentViewerBase viewer = _root as DocumentViewerBase;
            if (viewer != null)
            {

View on GitHub (pinned to 81131a70a4)