dotnet/wpf · error · InvalidOperationException
SR.AnnotationServiceNotEnabled
Error message
SR.AnnotationServiceNotEnabled
What it means
AnnotationService.Disable throws this InvalidOperationException when the service has not been enabled (the internal _isEnabled flag is false). Disable is only valid after a successful Enable call on the same service instance.
Solutions
- Guard the Disable call with AnnotationService.GetService(viewer) != null or a tracked bool before calling it.
- Structure teardown so Disable is called exactly once per Enable (e.g. set the service field to null after disabling).
Example fix
// before
service.Disable();
// after
if (AnnotationService.GetService(myViewer) is AnnotationService service)
service.Disable(); Defensive patterns
Strategy: type-guard
Validate before calling
bool isEnabled = AnnotationService.GetService(myViewer) != null;
Type guard
bool CanDisable(AnnotationService s) => AnnotationService.GetService(s != null ? GetViewer(s) : null) != null;
Try / catch
try { service.Disable(); } catch (InvalidOperationException) { /* never enabled; ignore */ } Prevention
- Pair every Enable with exactly one Disable
- Track service lifecycle state in your own field
- Make teardown idempotent
When it happens
Trigger: Calling Disable() on a service that was never enabled, or calling Disable() twice (double-teardown, e.g. in both a page unload handler and a Dispose method).
Common situations: See trigger scenarios.
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
- SR.FrameworkElementFactoryMustBeSealed
- SR.ObjectDisposed_StoreClosed
- anchorLocator.Parts
- annotation component
- Cannot reopen a popup in the closed event handler.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/29b08debf02579a1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/AnnotationService.cs:225
// Don't register on the store until the service is ready to accept events.
// Register for content change and anchor change events - we'll need to attach/detach
// annotations as they are added/removed from the store or their anchors change
annotationStore.StoreContentChanged += new StoreContentChangedEventHandler(OnStoreContentChanged);
annotationStore.AnchorChanged += new AnnotationResourceChangedEventHandler(OnAnchorChanged);
}
/// <summary>
/// Disables annotations on the DocumentViewerBase. Any visible annotations will
/// disappear. Service can be enabled again by calling Enable.
/// </summary>
/// <exception cref="InvalidOperationException">service isn't enabled</exception>
public void Disable()
{
VerifyAccess();
if (!_isEnabled)
throw new InvalidOperationException(SR.AnnotationServiceNotEnabled);
// If it hasn't been run yet, abort the pending operation. Still need to
// unregister and unload annotations. They may have been loaded due to a
// store event.
_asyncLoadOperation?.Abort();
_asyncLoadOperation = null;
// Unregister for changes to the store - add/deletes/anchor changes - before
// unloading annotations. We don't want any events between unloading and unregistering.
try
{
_store.StoreContentChanged -= new StoreContentChangedEventHandler(OnStoreContentChanged);
_store.AnchorChanged -= new AnnotationResourceChangedEventHandler(OnAnchorChanged);
}
finally
{
IDocumentPaginatorSource document;
DocumentViewerBase viewer;View on GitHub (pinned to 81131a70a4)