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

  1. Write xmlns declarations immediately after WriteStartElement for the root element, or after the corresponding *Start call for complex/array/list/dictionary scopes.
  2. Verify the surrounding Write* call sequence forms a valid BAML element tree before adding WriteXmlnsProperty.
  3. 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

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


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)