dotnet/wpf · error · XmlException

SR.Format(SR.InvalidXmlContent…

Error message

SR.Format(SR.InvalidXmlContent, AnnotationXmlConstants.Elements.ContentLocator)

What it means

While reading a ContentLocator element during annotation deserialization, ReadXml expects only Element nodes inside the locator. Any non-element node (text, comments, CDATA, whitespace-only content at a content position) causes XmlException(SR.InvalidXmlContent, "ContentLocator"). The reader is also expected to sit on the ContentLocator EndElement when the loop ends.

Solutions

  1. Fix the annotation XML so ContentLocator contains only well-formed locator-part child elements.
  2. Regenerate the annotation stream from a known-good source instead of hand-editing.
  3. Validate the XML against the annotation schema before passing the stream to the store.

Example fix

// before
<ContentLocator>some text<Part .../></ContentLocator>
// after
<ContentLocator><MyPart xmlns="http://schemas.microsoft.com/annotations"/></ContentLocator>
Defensive patterns

Strategy: try-catch

Validate before calling

// Before loading: ensure ContentLocator elements contain only element children
foreach (var locator in doc.Descendants("ContentLocator"))
    if (locator.Nodes().Any(n => n is XText t && !string.IsNullOrWhiteSpace(t.Value)))
        throw new InvalidDataException("ContentLocator contains non-element content");

Try / catch

try { store.LoadAnnotations(stream); }
catch (XmlException ex) when (ex.Message.Contains("ContentLocator")) { /* discard or repair the malformed annotation file */ }

Prevention

When it happens

Trigger: Deserializing an annotations stream where a <ContentLocator> contains text or unexpected markup, e.g. <ContentLocator>garbage</ContentLocator> or a child that is not a locator part element.

Common situations: Hand-edited annotation store files; annotation XML generated by other tools that include whitespace/text nodes or extra elements; corrupted streams; version drift where newer annotations embed unknown content.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/LocatorPartList.cs:207

        {
            ArgumentNullException.ThrowIfNull(reader);

            // We expect no attributes on a "ContentLocator", 
            // so throw using the name of one of the unexpected attributes
            Annotation.CheckForNonNamespaceAttribute(reader, AnnotationXmlConstants.Elements.ContentLocator);

            if (!reader.IsEmptyElement)
            {
                reader.Read();  // Reads the start of the "ContentLocator" element

                // ContentLocatorParts cannot write themselves out (see above).  They could read
                // themselves in but instead of having write code in one place and read 
                // code somewhere else - we keep it together in this class.
                while (!(AnnotationXmlConstants.Elements.ContentLocator == reader.LocalName && XmlNodeType.EndElement == reader.NodeType))
                {
                    if (XmlNodeType.Element != reader.NodeType)
                    {
                        throw new XmlException(SR.Format(SR.InvalidXmlContent, AnnotationXmlConstants.Elements.ContentLocator));
                    }

                    ContentLocatorPart part = new ContentLocatorPart(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI));
                    
                    // Read each of the Item elements within the ContentLocatorPart
                    if (!reader.IsEmptyElement)
                    {
                        // We expect no attributes on a locator part tag, 
                        // so throw using the name of one of the unexpected attributes
                        Annotation.CheckForNonNamespaceAttribute(reader, part.PartType.Name);

                        reader.Read(); // Read the start of the locator part tag

                        while (!(XmlNodeType.EndElement == reader.NodeType && part.PartType.Name == reader.LocalName))
                        {
                            if (AnnotationXmlConstants.Elements.Item == reader.LocalName && reader.NamespaceURI == AnnotationXmlConstants.Namespaces.CoreSchemaNamespace)
                            {
                                string name = null;

View on GitHub (pinned to 81131a70a4)