dotnet/wpf · error · XamlUnexpectedParseException
StartElement ::= . ELEMENT DIRECTIVE*.
Error message
StartElement ::= . ELEMENT DIRECTIVE*.
What it means
XamlPullParser.P_StartElement implements `StartElement ::= ELEMENT DIRECTIVE*`. It throws XamlUnexpectedParseException when the scanner's NodeType is not ELEMENT, i.e. the parser was asked to produce a start-object node sequence while the current scanner node is not a begin-element token. This guards the grammar contract for open-element tokens (<Tag>) handled by P_Element's second branch.
Solutions
- Fix the scanner so begin-element tokens set NodeType = ELEMENT (self-closing ones must be EMPTYELEMENT).
- Route parsing through P_Element rather than calling P_StartElement directly.
- Verify the input is well-formed XML and restart the reader if a previous exception desynchronized state.
- If a framework bug is suspected, reproduce minimally and upgrade the WPF/System.Xaml package.
Example fix
// before var nodes = parser.P_StartElement(); // NodeType was not ELEMENT // after var nodes = parser.P_Element(); // validates EMPTYELEMENT vs ELEMENT itself
Defensive patterns
Strategy: try-catch
Try / catch
try { return XamlReader.Parse(xaml); } catch (XamlUnexpectedParseException ex) { Log($"Expected ELEMENT node, got {ex.NodeType}"); return null; } Prevention
- Route parsing through P_Element, not P_StartElement directly
- Custom scanners must classify '<Tag>' as ELEMENT
- Restart the reader after any parse exception to avoid desync
When it happens
Trigger: P_Element's start-element branch entered while the scanner node is not ELEMENT — from a custom scanner emitting wrong node types, or from invoking P_StartElement outside the P_Element flow; also from corrupted scanner state on malformed input.
Common situations: Custom reader/scanner implementations failing to classify '<Tag>' as ScannerNodeType.ELEMENT; tests calling P_StartElement directly without positioning the scanner; desynchronized scanner after prior parse errors.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- EmptyElement ::= . EMPTYELEMENT DIRECTIVE* ATTRIBUTE*.
- Element ::= . EmptyElement | ( StartElement ElementBody ).
- ElementBody ::= ATTRIBUTE* ( PropertyElement | Content )* …
- EmptyPropertyElement ::= EMPTYPROPERTYELEMENT.
- NonemptyPropertyElement ::= . PROPERTYELEMENT Content?…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8618bcb55fdd92fb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/XamlPullParser.cs:176
_xamlScanner.Read();
if (ProvideLineInfo)
{
yield return Logic_LineInfo();
}
}
yield return Logic_EndOfAttributes();
yield return Logic_EndObject();
}
///////////////////////////
// StartElement ::= ELEMENT DIRECTIVE*
//
public IEnumerable<XamlNode> P_StartElement()
{
if (_xamlScanner.NodeType != ScannerNodeType.ELEMENT)
{
throw new XamlUnexpectedParseException(_xamlScanner, _xamlScanner.NodeType,
StartElementRuleException);
}
yield return Logic_StartObject(_xamlScanner.Type, _xamlScanner.Namespace);
_xamlScanner.Read();
if (ProvideLineInfo)
{
yield return Logic_LineInfo();
}
while (_xamlScanner.NodeType == ScannerNodeType.DIRECTIVE)
{
// Directives are processed exactly like Attributes.
foreach (XamlNode node in LogicStream_Attribute())
{
yield return node;
}
View on GitHub (pinned to 81131a70a4)