dotnet/wpf · error

SR.BamlWriterUnknownMarkupExtension

Error message

SR.BamlWriterUnknownMarkupExtension

What it means

During markup-extension expansion, ProcessMarkupExtensionNodes replays buffered XAML nodes and writes them as BAML records; its switch has no case for the node type it received, so it throws InvalidOperationException(SR.BamlWriterUnknownMarkupExtension). It means the writer encountered an unexpected XamlNodeType while expanding a markup extension — an internal protocol/state violation rather than bad user data per se.

Solutions

  1. Simplify the markup extension in the source XAML (e.g. replace complex nested extensions with resource references or plain values).
  2. Update to a patched WPF version if the node type is legitimately supported upstream.
  3. Pre-expand markup extensions to literal values (via IXamlSchemaContextProvider/MarkupExtension resolution) before BAML writing.

Example fix

// before
<Button Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}" />
// after
<Button Background="{StaticResource ControlBrush}" /> <!-- simpler, pre-resolvable extension -->
Defensive patterns

Strategy: try-catch

Validate before calling

// Reject exotic/unrecognized markup extension nodes before feeding the writer:
var known = new[] { typeof(StaticResourceExtension), typeof(DynamicResourceExtension), typeof(Binding), typeof(TemplateBindingExtension) };
bool isKnownExtension(object ext) => known.Contains(ext.GetType());

Type guard

bool IsSupportedExtensionType(object me) =>
    me is StaticResourceExtension || me is DynamicResourceExtension ||
    me is Binding || me is TemplateBindingExtension;

Try / catch

try { /* serialization step that flushes markup extension nodes */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("markup extension"))
{
    // retry after pre-expanding the offending extension to a literal value
}

Prevention

When it happens

Trigger: A markup extension (e.g. StaticResource, Binding, TemplateBinding) expansion produces a node type outside the handled set while being flushed by WriteStartElement, WriteEndElement, WriteStartComplexProperty, WriteLiteralContent, WritePIMapping, or WriteText; feeding nodes the writer's state machine did not anticipate.

Common situations: Custom or exotic markup extensions in serialized XAML; node-stream order anomalies from a preceding XamlReader stage; WPF framework bugs in rarely used extension constructs.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlWriter.cs:997

                    _bamlRecordWriter.WritePropertyComplexStart((XamlPropertyComplexStartNode)node);
                    break;
                case XamlNodeType.PropertyComplexEnd:
                    _bamlRecordWriter.WritePropertyComplexEnd((XamlPropertyComplexEndNode)node);
                    break;
                case XamlNodeType.Text:
                    _bamlRecordWriter.WriteText((XamlTextNode)node);
                    break;
                case XamlNodeType.EndAttributes:
                    _bamlRecordWriter.WriteEndAttributes((XamlEndAttributesNode)node);
                    break;
                case XamlNodeType.ConstructorParametersStart:
                    _bamlRecordWriter.WriteConstructorParametersStart((XamlConstructorParametersStartNode)node);
                    break;
                case XamlNodeType.ConstructorParametersEnd:
                    _bamlRecordWriter.WriteConstructorParametersEnd((XamlConstructorParametersEndNode)node);
                    break;
                default:
                    throw new InvalidOperationException(SR.BamlWriterUnknownMarkupExtension);
            }
        }
        _markupExtensionNodes.Clear();
    }

    /***************************************************************************\
    *
    * BamlWriter.VerifyWriteState
    *
    * Verify that we are in a good state to perform a record write.  Throw
    * appropriate exceptions if not.
    *
    \***************************************************************************/
    
    private void VerifyWriteState()
    {
        if (_closed)
        {

View on GitHub (pinned to 81131a70a4)