dotnet/wpf · error · InvalidOperationException

InvalidOperationException(SR.Format(SR.XamlXmlWriterWriteNot…

Error message

InvalidOperationException(SR.Format(SR.XamlXmlWriterWriteNotSupportedInCurrentState, "WriteStartMember")) [content property, non-empty frame]

What it means

For a content property (property == containingType.ContentProperty), XamlXmlWriter switches to TryContentProperty state, which is only possible when the current frame is empty. If WriteStartMember is called for the content property while another member framing is active (non-empty namespaceScope frame), it throws InvalidOperationException 'WriteStartMember not supported in current state' because content-property shorthand cannot be nested inside an open member.

Solutions

  1. End the open member with WriteEndMember before starting the content property
  2. Reorder emission so the content property is written after all regular members are closed
  3. Generate the stream via XamlObjectReader to guarantee legal member ordering

Example fix

// before
writer.WriteStartMember(other);
writer.WriteStartMember(contentProp); // non-empty frame -> throws
// after
writer.WriteStartMember(other);
writer.WriteEndMember();
writer.WriteStartMember(contentProp);
Defensive patterns

Strategy: try-catch

Validate before calling

if (property == containingType.ContentProperty && !currentFrameIsEmpty) throw new InvalidOperationException("Content property requires empty frame");

Type guard

bool CanStartContentProperty(XamlMember p, XamlType t, bool frameEmpty) => p != t.ContentProperty || frameEmpty;

Try / catch

try { writer.WriteStartMember(property); }
catch (InvalidOperationException ex) when (ex.Message.Contains("WriteStartMember")) { /* end open member first, then retry */ }

Prevention

When it happens

Trigger: WriteStartMember with the type's ContentProperty while a previous member in the same object frame has not been ended (namespaceScopes.Peek().IsEmpty() == false).

Common situations: Serializing objects where a regular member was opened before the content property without WriteEndMember; custom writers that emit content property inside attribute-like framing; generated code writing members out of order.

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/32a51838fab33911. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs:1048

                if ((property == XamlLanguage.Items && parentType is not null && parentType.IsWhitespaceSignificantCollection) ||
                    (property == XamlLanguage.UnknownContent))
                {
                    writer.isFirstElementOfWhitespaceSignificantCollection = true;
                }

                XamlType containingType = writer.namespaceScopes.Peek().Type;
                if (IsImplicit(property))
                {
                    if (!writer.namespaceScopes.Peek().IsEmpty())
                    {
                        throw new InvalidOperationException(SR.Format(SR.XamlXmlWriterWriteNotSupportedInCurrentState, "WriteStartMember"));
                    }
                }
                else if (property == containingType.ContentProperty)
                {
                    if (!writer.namespaceScopes.Peek().IsEmpty())
                    {
                        throw new InvalidOperationException(SR.Format(SR.XamlXmlWriterWriteNotSupportedInCurrentState, "WriteStartMember"));
                    }
                    else
                    {
                        writer.currentState = TryContentProperty.State;
                        return;
                    }
                }
                else
                {
                    WriteMemberAsElement(writer);
                    writer.WriteDeferredNamespaces(XamlNodeType.StartMember);
                }

                if (property == XamlLanguage.PositionalParameters)
                {
                    // the writer is not in a state where it can write markup extensions in curly form
                    // so it expands the positional parameters as properties.

View on GitHub (pinned to 81131a70a4)