dotnet/wpf · error · XamlUnexpectedParseException

PropertyElement ::= EmptyPropertyElement |…

Error message

PropertyElement ::= EmptyPropertyElement | NonemptyPropertyElement

What it means

XamlPullParser's P_PropertyElement implements the grammar rule PropertyElement ::= EmptyPropertyElement | NonemptyPropertyElement and dispatches on the scanner's current node type. If the scanner produces a node type that is neither EMPTYPROPERTYELEMENT nor PROPERTYELEMENT where a property element must appear, the parser throws XamlUnexpectedParseException. This means the XAML markup is structurally invalid at that position.

Solutions

  1. Fix the XAML so the element inside the property element is a legal property element (<Owner.Property>...</Owner.Property> or self-closing <Owner.Property/>)
  2. Validate the markup with an XML/XSD validator before feeding it to the XAML reader to catch nesting errors early
  3. Check for stray text nodes or misplaced end tags at the reported line/position from the parse exception

Example fix

// before (invalid: text where a property element is required)
<Button><Click>Handler</Click></Button>
// after
<Button Click="Handler" />
Defensive patterns

Strategy: validation

Validate before calling

using var xr = System.Xml.XmlReader.Create(path); try { while (xr.Read()) { } } catch (System.Xml.XmlException ex) { throw new InvalidOperationException($"Malformed XAML at {ex.LineNumber}:{ex.LinePosition}", ex); }

Type guard

static bool IsWellFormedXml(string xaml) { try { var d = new System.Xml.XmlDocument(); d.LoadXml(xaml); return true; } catch { return false; } }

Try / catch

try { ParseXaml(stream); } catch (System.Xaml.XamlParseException ex) { Log($"XAML structure invalid at {ex.LineNumber}:{ex.LinePosition}: {ex.Message}"); throw; }

Prevention

When it happens

Trigger: Calling XamlXmlReader/XamlPullParser over markup where a nested element inside a property element is not a well-formed property element (e.g. stray text or an unexpected node kind between <x:Members> style property elements). Reached via P_ElementBody → P_PropertyElement when the scanner's NodeType falls into the default (unexpected) case of the switch.

Common situations: Hand-edited XAML with mismatched or mistyped tags; markup generated by a tool that emits invalid nesting; copying XAML fragments between documents where a property-element position receives something else (attribute-style content, text, or an end tag).

Related errors


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

Appendix: source

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

            switch (nodeType)
            {
                case ScannerNodeType.EMPTYPROPERTYELEMENT:
                    foreach (XamlNode node in P_EmptyPropertyElement())
                    {
                        yield return node;
                    }

                    break;
                case ScannerNodeType.PROPERTYELEMENT:
                    foreach (XamlNode node in P_NonemptyPropertyElement())
                    {
                        yield return node;
                    }

                    break;
                default:
                    throw new XamlUnexpectedParseException(_xamlScanner, nodeType,
                        PropertyElementRuleException);
            }
        }

        ///////////////////////////
        //  EmptyPropertyElement ::= EMPTYPROPERTYELEMENT
        //
        public IEnumerable<XamlNode> P_EmptyPropertyElement()
        {
            if (_xamlScanner.NodeType != ScannerNodeType.EMPTYPROPERTYELEMENT)
            {
                throw new XamlUnexpectedParseException(_xamlScanner, _xamlScanner.NodeType,
                    EmptyPropertyElementRuleException);
            }

            yield return Logic_StartMember(_xamlScanner.PropertyElement);
            yield return Logic_EndMember();
            _xamlScanner.Read();

View on GitHub (pinned to 81131a70a4)