dotnet/wpf · error · InvalidOperationException
SR.BamlWriterBadXmlns
Error message
SR.BamlWriterBadXmlns: {0} {1} What it means
WriteXmlnsProperty (xmlns declarations) may only be written when the current parent record is an ElementStart or the start of a complex property, array, IList, or IDictionary. Otherwise the writer throws InvalidOperationException(SR.BamlWriterBadXmlns, "WriteXmlnsProperty", parentType), naming the unexpected record type. BAML grammar restricts namespace declarations to these container scopes.
Solutions
- Write xmlns declarations immediately after WriteStartElement for the root element, or after the corresponding *Start call for complex/array/list/dictionary scopes.
- Verify the surrounding Write* call sequence forms a valid BAML element tree before adding WriteXmlnsProperty.
- Log or assert PeekRecordType() before each WriteXmlnsProperty during development to catch scope mistakes early.
Example fix
// before
writer.WriteStartDocument();
writer.WriteXmlnsProperty("x", xamlNamespace); // no element open yet
// after
writer.WriteStartDocument();
writer.WriteStartElement(rootType, localAssembly, assemblyVersion);
writer.WriteXmlnsProperty("x", xamlNamespace); Defensive patterns
Strategy: validation
Validate before calling
static readonly BamlRecordType[] XmlnsScopes =
{
BamlRecordType.ElementStart, BamlRecordType.PropertyComplexStart,
BamlRecordType.PropertyArrayStart, BamlRecordType.PropertyIListStart,
BamlRecordType.PropertyIDictionaryStart
};
bool CanWriteXmlns(BamlRecordType t) => XmlnsScopes.Contains(t); Try / catch
try { writer.WriteXmlnsProperty(prefix, ns); }
catch (InvalidOperationException ex) when (ex.Message.Contains("WriteXmlnsProperty"))
{
// log scope mismatch and skip or reposition the xmlns write
} Prevention
- Emit xmlns declarations right after the element/array/list/dictionary start.
- Mirror the parser's expected xmlns placement (root element, collection scopes).
- Unit-test serializers with namespace-heavy XAML.
When it happens
Trigger: Calling WriteXmlnsProperty after WriteEndDocument, directly after the document start (no element opened), after WriteDefAttribute/WriteProperty in a non-container scope, or inside a plain property scope where the top record is none of the five allowed types.
Common situations: Emitting xmlns mappings at the wrong nesting level in a hand-rolled serializer; writing xmlns after element content instead of at element start; state-machine bugs that leave the record stack in an unexpected type.
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.BamlWriterBadScope
- SR.BamlWriterNoInElement
- SR.BamlWriterStartDoc
- SR.BamlBadExtensionValue
- SR.BamlWriterUnknownMarkupExtension
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f4de0e23193b47c0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlWriter.cs:470
/// <remarks>
/// This is used for setting the default namespace, or for mapping
/// a namespace prefix (or localName) to a namespace. If prefix is
/// an empty string, then this sets the default namespace.
/// </remarks>
public void WriteXmlnsProperty(
string localName,
string xmlNamespace)
{
VerifyWriteState();
BamlRecordType parentType = PeekRecordType();
if (parentType != BamlRecordType.ElementStart &&
parentType != BamlRecordType.PropertyComplexStart &&
parentType != BamlRecordType.PropertyArrayStart &&
parentType != BamlRecordType.PropertyIListStart &&
parentType != BamlRecordType.PropertyIDictionaryStart)
{
throw new InvalidOperationException(SR.Format(SR.BamlWriterBadXmlns,
"WriteXmlnsProperty",
parentType.ToString()));
}
XamlXmlnsPropertyNode xmlnsNode = new XamlXmlnsPropertyNode(
0,
0,
_depth,
localName,
xmlNamespace);
_bamlRecordWriter.WriteNamespacePrefix(xmlnsNode);
_parserContext.XmlnsDictionary[localName] = xmlNamespace;
}
/// <summary>
/// Write an attribute in the Definition namespace.
/// </summary>View on GitHub (pinned to 81131a70a4)