dotnet/wpf · error · XamlUnexpectedParseException

ElementBody ::= ATTRIBUTE* ( PropertyElement | Content )* …

Error message

ElementBody ::= ATTRIBUTE* ( PropertyElement | Content )* . ENDTAG.

What it means

XamlPullParser.P_ElementBody implements `ElementBody ::= ATTRIBUTE* (PropertyElement | Content)* ENDTAG`. After consuming attributes, property elements, and content, it requires the current scanner node to be ENDTAG (</Tag>); if it is not, it throws XamlUnexpectedParseException with the ElementBody rule. This detects elements that end without a proper closing tag before the parser emits its EndObject node.

Solutions

  1. Add the missing </Tag> so every open element has a matching end tag.
  2. Check tag-name spelling/casing — mismatched names prevent ENDTAG recognition.
  3. Validate the document as XML (xmllint or IDE validation) before XamlReader.Load.
  4. If building XAML programmatically, ensure each StartElement is paired with an end; consider emitting self-closing <Tag/> for empty elements.

Example fix

<!-- before -->
<StackPanel>
  <TextBlock Text="Hi" />

<!-- after -->
<StackPanel>
  <TextBlock Text="Hi" />
</StackPanel>
Defensive patterns

Strategy: validation

Validate before calling

// Detect unclosed elements before Load
var settings = new System.Xml.XmlReaderSettings { ConformanceLevel = System.Xml.ConformanceLevel.Document };
using (var xr = System.Xml.XmlReader.Create(new System.IO.StringReader(xaml), settings)) { while (xr.Read()) { } } // throws on mismatched/missing end tags

Try / catch

try { return XamlReader.Parse(xaml); } catch (XamlUnexpectedParseException ex) { Log($"Missing ENDTAG near {ex.LineNumber}:{ex.LinePosition}"); return null; }

Prevention

When it happens

Trigger: XAML where an element's content/property elements end but no matching </Tag> follows — e.g. mismatched tag names, an unclosed child element swallowing the parent's end tag, or an EOF reached before ENDTAG during XamlReader.Load.

Common situations: Hand-edited XAML with mismatched or missing closing tags; string-generated markup missing an end tag; merging XAML fragments where a nested element was not fully closed; truncation of the XAML stream mid-element.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/XamlPullParser.cs:303

                    if (!hasContent && hasTypeConverter && !isConstructable)
                    {
                        yield return Logic_StartInitProperty(currentType);
                        yield return new XamlNode(XamlNodeType.Value, string.Empty);
                        yield return Logic_EndMember();
                    }

                    doneWithElementContent = true;
                    break;
                default:
                    doneWithElementContent = true;
                    break;
                }
            }
            while (!doneWithElementContent);

            if (_xamlScanner.NodeType != ScannerNodeType.ENDTAG)
            {
                throw new XamlUnexpectedParseException(_xamlScanner, _xamlScanner.NodeType,
                    ElementBodyRuleException);
            }

            yield return Logic_EndObject();
            _xamlScanner.Read();
            if (ProvideLineInfo)
            {
                yield return Logic_LineInfo();
            }
        }

        ///////////////////////////
        //  PropertyElement ::= EmptyPropertyElement | NonemptyPropertyElement
        //
        public IEnumerable<XamlNode> P_PropertyElement()
        {
            ScannerNodeType nodeType = _xamlScanner.NodeType;

View on GitHub (pinned to 81131a70a4)