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
- Fix the XAML so the element inside the property element is a legal property element (<Owner.Property>...</Owner.Property> or self-closing <Owner.Property/>)
- Validate the markup with an XML/XSD validator before feeding it to the XAML reader to catch nesting errors early
- 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
- Validate markup with an XML parser before XAML parsing
- Keep property elements as Owner.Property tags only — no stray text nodes inside
- Use the XAML designer or a schema-aware editor to author markup
- Never reuse a partially consumed XamlXmlReader
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
- Element ::= . EmptyElement | ( StartElement ElementBody ).
- EmptyPropertyElement ::= EMPTYPROPERTYELEMENT.
- NonemptyPropertyElement ::= . PROPERTYELEMENT Content?…
- ElementBody ::= ATTRIBUTE* ( PropertyElement | Content )* …
- EmptyElement ::= . EMPTYELEMENT DIRECTIVE* ATTRIBUTE*.
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)