dotnet/wpf · error · ArgumentException

SR.AnnotationAlreadyExists

Error message

SR.AnnotationAlreadyExists

What it means

XmlStreamStore.AddAnnotation rejects annotations whose Id already exists in the store, throwing ArgumentException(SR.AnnotationAlreadyExists, nameof(newAnnotation)). Annotation Ids are unique keys within the store, so adding a duplicate would corrupt the store's invariants.

Solutions

  1. Check GetAnnotations() or the annotation's existence before adding, and skip or update instead of adding duplicates.
  2. Generate a fresh unique Id (Guid) when re-adding a copied annotation.
  3. For updates to an existing annotation, use the appropriate update/modify API rather than AddAnnotation.

Example fix

// before
store.AddAnnotation(loadedAnnotation); // throws if Id already stored
// after
if (store.GetAnnotations(new Guid(loadedAnnotation.Id.ToString())).FirstOrDefault() == null)
    store.AddAnnotation(loadedAnnotation);
else
    loadedAnnotation = new Annotation(Guid.NewGuid(), loadedAnnotation.Cargos); // new Id for the copy
Defensive patterns

Strategy: validation

Validate before calling

bool exists = store.GetAnnotations().Cast<Annotation>().Any(a => a.Id == newAnnotation.Id);
if (!exists) store.AddAnnotation(newAnnotation);

Try / catch

try { store.AddAnnotation(newAnnotation); }
catch (ArgumentException ex) when (ex.Message.Contains("already exists")) { /* treat as duplicate: update or skip */ }

Prevention

When it happens

Trigger: Calling store.AddAnnotation(annotation) with an annotation whose Id matches one already persisted (or already present in the in-memory store map), e.g. re-adding a loaded annotation or cloning one without regenerating its Id.

Common situations: Re-running an import routine without clearing the store; copying annotation objects (clone/copy constructors preserve Id); deserializing the same annotation twice into one store.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

        public override void AddAnnotation(Annotation newAnnotation)
        {
            ArgumentNullException.ThrowIfNull(newAnnotation);

            // We are going to modify internal data. Lock the object
            // to avoid modifications from other threads
            lock (SyncRoot)
            {
                //fire trace event
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAnnotationBegin);
                try
                {
                    CheckStatus();

                    XPathNavigator editor = GetAnnotationNodeForId(newAnnotation.Id);

                    // we are making sure that the newAnnotation doesn't already exist in the store
                    if (editor != null)
                        throw new ArgumentException(SR.AnnotationAlreadyExists, nameof(newAnnotation));

                    // we are making sure that the newAnnotation doesn't already exist in the store map
                    if (_storeAnnotationsMap.FindAnnotation(newAnnotation.Id) != null)
                        throw new ArgumentException(SR.AnnotationAlreadyExists, nameof(newAnnotation));

                    // simply add the annotation to the map to save on performance
                    // notice that we need to tell the map that this instance of the annotation is dirty
                    _storeAnnotationsMap.AddAnnotation(newAnnotation, true);
                }
                finally
                {
                    //fire trace event
                    EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAnnotationEnd);
                }
			}

            OnStoreContentChanged(new StoreContentChangedEventArgs(StoreContentAction.Added, newAnnotation));
        }

View on GitHub (pinned to 81131a70a4)