{"record":{"id":"ed36232db5f083b0","repo":"dotnet/wpf","slug":"sr-parsertypeconvertertextunusable","errorCode":null,"errorMessage":"SR.ParserTypeConverterTextUnusable","messagePattern":"SR\\.ParserTypeConverterTextUnusable","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderHelper.cs","lineNumber":6039,"sourceCode":"                    // Example that would trip this error:\n                    //  <FontFamily>Symbol<FontFamily.Baseline>12.345</FontFamily.Baseline></FontFamily>\n                    throw new InvalidOperationException(SR.Format(SR.ParserAbandonedTypeConverterText,_typeConverterTextWrittenAndNotProcessed));\n                }\n                _typeConverterDecisionState = TypeConverterDecisionState.Uninitialized;\n                _typeConverterCandidateIndex = 0;\n                _typeConverterTextWrittenAndNotProcessed = null;\n            }\n\n            // Called by CompileText (or helper methods) when they are sending text\n            //  that they think is TypeConverter input.  For proper TypeConverter\n            //  syntax, we must be at a point where we're processing ElementStart.\n            internal void WritingTypeConverterText(string initializationText)\n            {\n                if( _typeConverterDecisionState != TypeConverterDecisionState.ElementStart )\n                {\n                    // Example that would trip this error:\n                    //  <FontFamily Baseline=\"12.345\">Symbol</FontFamily>\n                    throw new InvalidOperationException(SR.Format(SR.ParserTypeConverterTextUnusable,initializationText));\n                }\n\n                _typeConverterTextWrittenAndNotProcessed = initializationText;\n            }\n\n            // A new node has been inserted into the middle of the XamlNode queue.\n            //  See if this invalidates TypeConverter syntax.\n            private void ExamineInsertedNode(XamlNode xamlNode, int insertionIndex)\n            {\n                if( _typeConverterDecisionState != TypeConverterDecisionState.Uninitialized )\n                {\n                    // This method only cares about the new node if we're in the middle of\n                    //  a potential TypeConverter sequence.\n                    // This is a shortcut enabled by the current design, where only a\n                    //  limited set of XamlNodes can be legally inserted out-of-order.\n                    if( NodeTypePrecludesTypeConverterUse(xamlNode) )\n                    {\n                        // The newly inserted node breaks our ability to use TypeConverter","sourceCodeStart":6021,"sourceCodeEnd":6057,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderHelper.cs#L6021-L6057","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n<FontFamily Baseline=\"12.345\">Symbol</FontFamily>\n// after\n<FontFamily Baseline=\"12.345\"><FontFamily.Family>Symbol</FontFamily.Family></FontFamily> // or split into separate elements","handlingStrategy":"validation","validationCode":"// supply converted values as attributes, not as text alongside attributes\nbool hasText = el.Nodes().OfType<XText>().Any(n => !string.IsNullOrWhiteSpace(n.Value));\nbool hasAttrs = el.Attributes().Any(a => !a.IsNamespaceDeclaration);\nif (hasText && hasAttrs) throw new InvalidOperationException($\"<{el.Name}> mixes text and attributes competing for TypeConverter conversion\");","typeGuard":null,"tryCatchPattern":"try { writer.WriteNode(node); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"TypeConverter\")) { log.Error(ex); throw; }","preventionTips":["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."],"tags":["wpf","xaml","typeconverter","writer"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}