dotnet/wpf · error · InvalidOperationException
SR.ParserTypeConverterTextUnusable
Error message
SR.ParserTypeConverterTextUnusable
What it means
InvalidOperationException with SR.ParserTypeConverterTextUnusable thrown by WritingTypeConverterText when initialization text for a TypeConverter is written while the parser is not in the ElementStart decision state, meaning the text cannot legally initialize the element being created.
Solutions
- Restructure XAML so converted values go in attributes and text content is used alone, not both competing for the constructor conversion.
- Provide the value via a property element or explicit constructor syntax instead of element text.
- If driving the writer API directly, ensure WritingTypeConverterText is called immediately after ElementStart when TypeConverterDecisionState is ElementStart.
- Split the element into two elements so each has a single conversion source.
Example fix
// before <FontFamily Baseline="12.345">Symbol</FontFamily> // after <FontFamily Baseline="12.345"><FontFamily.Family>Symbol</FontFamily.Family></FontFamily> // or split into separate elements
Defensive patterns
Strategy: validation
Validate before calling
// supply converted values as attributes, not as text alongside attributes
bool hasText = el.Nodes().OfType<XText>().Any(n => !string.IsNullOrWhiteSpace(n.Value));
bool hasAttrs = el.Attributes().Any(a => !a.IsNamespaceDeclaration);
if (hasText && hasAttrs) throw new InvalidOperationException($"<{el.Name}> mixes text and attributes competing for TypeConverter conversion"); Try / catch
try { writer.WriteNode(node); } catch (InvalidOperationException ex) when (ex.Message.Contains("TypeConverter")) { log.Error(ex); throw; } Prevention
- Prefer attributes for converted values; use text only when it is the sole content.
- When driving writer APIs, emit converter text only immediately after ElementStart.
- Split elements with multiple conversion sources into separate elements.
When it happens
Trigger: Calling the writer path so that type-converter text (e.g. element initialization text) is emitted after the element start was not the current type-converter decision state — e.g. XAML like <FontFamily Baseline="12.345">Symbol</FontFamily> where attribute processing already engaged the converter machinery.
Common situations: Element supplies both attributes that require conversion and text content, so the text can't be used as constructor initialization text; typically hit in BAML-generation or writer pipelines re-serializing XAML.
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
- SR.Format(SR.InvalidStringVirtualizationCacheLength, s)
- SR.ParserAbandonedTypeConverterText
- SR.ParserTypeConverterTextNeedsEndElement
- SR.TextRange_InvalidParameterValue
- is not a valid value for .
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ed36232db5f083b0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderHelper.cs:6039
// Example that would trip this error:
// <FontFamily>Symbol<FontFamily.Baseline>12.345</FontFamily.Baseline></FontFamily>
throw new InvalidOperationException(SR.Format(SR.ParserAbandonedTypeConverterText,_typeConverterTextWrittenAndNotProcessed));
}
_typeConverterDecisionState = TypeConverterDecisionState.Uninitialized;
_typeConverterCandidateIndex = 0;
_typeConverterTextWrittenAndNotProcessed = null;
}
// Called by CompileText (or helper methods) when they are sending text
// that they think is TypeConverter input. For proper TypeConverter
// syntax, we must be at a point where we're processing ElementStart.
internal void WritingTypeConverterText(string initializationText)
{
if( _typeConverterDecisionState != TypeConverterDecisionState.ElementStart )
{
// Example that would trip this error:
// <FontFamily Baseline="12.345">Symbol</FontFamily>
throw new InvalidOperationException(SR.Format(SR.ParserTypeConverterTextUnusable,initializationText));
}
_typeConverterTextWrittenAndNotProcessed = initializationText;
}
// A new node has been inserted into the middle of the XamlNode queue.
// See if this invalidates TypeConverter syntax.
private void ExamineInsertedNode(XamlNode xamlNode, int insertionIndex)
{
if( _typeConverterDecisionState != TypeConverterDecisionState.Uninitialized )
{
// This method only cares about the new node if we're in the middle of
// a potential TypeConverter sequence.
// This is a shortcut enabled by the current design, where only a
// limited set of XamlNodes can be legally inserted out-of-order.
if( NodeTypePrecludesTypeConverterUse(xamlNode) )
{
// The newly inserted node breaks our ability to use TypeConverterView on GitHub (pinned to 81131a70a4)