dotnet/wpf · error · InvalidOperationException

SR.ParserTypeConverterTextNeedsEndElement

Error message

SR.ParserTypeConverterTextNeedsEndElement

What it means

InvalidOperationException with SR.ParserTypeConverterTextNeedsEndElement thrown when pending TypeConverter text was written but instead of the matching end element the parser encounters a new element start (e.g. a nested element), so the buffered text can never be processed as the element's conversion input.

Solutions

  1. Close the text-only element before starting any child element: move the child element outside the parent.
  2. If the parent should contain children, don't rely on TypeConverter text — set the text via a property element or attribute.
  3. Verify closing tags match the correct elements to avoid stray nesting.
  4. Simplify the markup so each element has either text content or element children, never text + children mixed.

Example fix

// before
<FontFamily>Symbol<Button/></FontFamily>
// after
<FontFamily>Symbol</FontFamily>
<Button/>
Defensive patterns

Strategy: validation

Validate before calling

// text-only elements must not contain child elements
bool hasText = el.Nodes().OfType<XText>().Any(n => !string.IsNullOrWhiteSpace(n.Value));
if (hasText && el.Elements().Any()) throw new InvalidOperationException($"<{el.Name}> has text content plus child elements");

Try / catch

try { return (T)XamlReader.Parse(xaml); } catch (InvalidOperationException ex) when (ex.Message.Contains("end")) { log.Error(ex.Message); throw; }

Prevention

When it happens

Trigger: Parsing XAML like <FontFamily>Symbol<Button/></FontFamily> — text content followed by a child element before the parent's end tag, while the type-converter decision machinery expects the end element to flush the text.

Common situations: Accidentally nesting elements inside an element whose content is plain text for a TypeConverter (typo in markup, wrong closing tag, copy/paste of children into a text-only element).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderHelper.cs:6165

                {
                    // We've just seen the InitializationString, we expect it to be immediately
                    //  followed by an ElementEnd.
                    if( xamlNode.TokenType == XamlNodeType.ElementEnd )
                    {
                        Debug.Assert(((XamlNode)_xamlNodes[_typeConverterCandidateIndex]).TokenType==XamlNodeType.ElementStart,
                            "We've lost track of the ElementStart node, and we're about to die with a cast exception.  See if the ElementStart is still in the ArrayList somewhere, and find out why the pointer got out of sync.");

                        // We've seen the full <ElementStart>InitializationText</ElementEnd> sequence.
                        ((XamlElementStartNode)_xamlNodes[_typeConverterCandidateIndex]).CreateUsingTypeConverter = true;

                        // The initializationString would be used as input to the candidate element's TypeConverter.
                        _typeConverterTextWrittenAndNotProcessed = null;
                    }
                    else
                    {
                        // Example that would trip this error:
                        //  <FontFamily>Symbol<Button/></FontFamily>
                        throw new InvalidOperationException(SR.Format(SR.ParserTypeConverterTextNeedsEndElement, _typeConverterTextWrittenAndNotProcessed));
                    }

                    // One set of XamlNodes for TypeConverter done, start watching for another.
                    ResetTypeConverterDecision();
                }
                return;
            }

            // Checking the given XamlNode against the list of types that we know will
            //  break our ability to use TypeConverter.
            private bool NodeTypePrecludesTypeConverterUse(XamlNode xamlNode)
            {
                XamlNodeType tokenType = xamlNode.TokenType;

                switch(tokenType)
                {
                    /////////////////////////////////////////////////////////////
                    //

View on GitHub (pinned to 81131a70a4)