dotnet/wpf · error · InvalidOperationException
SR.BamlWriterNoInElement
Error message
SR.BamlWriterNoInElement: {0} {1} What it means
WriteProperty must be called while the writer's record stack top is an ElementStart record. When the parent record type is anything else, the writer throws InvalidOperationException(SR.BamlWriterNoInElement, "WriteProperty", parentType), reporting the offending record type in the message. This enforces valid BAML structure: properties can only be written directly inside an element.
Solutions
- Ensure the last call was WriteStartElement (not WriteStartComplexProperty/array/list) before WriteProperty.
- Use WriteStartComplexProperty/WriteEndComplexProperty for nested property scopes rather than attempting WriteProperty inside them.
- Wrap property writes in a state check or assert that the current scope is an element.
Example fix
// before
writer.WriteStartComplexProperty("Grid.Children");
writer.WriteProperty("Width", "100"); // wrong scope
// after
writer.WriteStartElement("Button", "Button", "...");
writer.WriteProperty("Width", "100"); Defensive patterns
Strategy: try-catch
Validate before calling
void EnsureElementScope(BamlWriter w, Func<BamlRecordType> peek)
{
if (peek() != BamlRecordType.ElementStart)
throw new InvalidOperationException("WriteProperty requires ElementStart scope");
} Try / catch
try { writer.WriteProperty(name, value); }
catch (InvalidOperationException ex) when (ex.Message.Contains("WriteProperty"))
{
// recover: re-enter element scope or abort serialization
} Prevention
- Track the current BAML scope in your serializer wrapper.
- Only emit properties immediately after WriteStartElement.
- Use separate methods for element properties vs complex property children.
When it happens
Trigger: Calling WriteProperty after WriteStartElement on a nested/complex property, after WriteEndComplexProperty without re-entering an element, after WriteEndDocument, or in any state where PeekRecordType() != BamlRecordType.ElementStart.
Common situations: Emitting a property while inside a complex property or array/IList scope; forgetting to close and reopen an element around properties; interleaving WriteProperty and WriteStartElement incorrectly in a hand-rolled serializer.
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.BamlWriterBadXmlns
- SR.BamlWriterStartDoc
- SR.BamlBadExtensionValue
- SR.BamlWriterUnknownMarkupExtension
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/cd68991aebd1e115.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlWriter.cs:303
/// Custom serialization record. Note that for custom serialization
/// to work, the assembly that contains the property's type must be
/// loaded. If custom serialization is not chosen, then
/// write out a 'normal' record, which will cause type conversion to happen
/// at load time from the stored string.
/// </remarks>
public void WriteProperty(
string assemblyName,
string ownerTypeFullName,
string propName,
string value,
BamlAttributeUsage propUsage)
{
VerifyWriteState();
BamlRecordType parentType = PeekRecordType();
if (parentType != BamlRecordType.ElementStart)
{
throw new InvalidOperationException(SR.Format(SR.BamlWriterNoInElement,
"WriteProperty",
parentType.ToString()));
}
object dpOrPi;
Type declaringType;
GetDpOrPi(assemblyName, ownerTypeFullName, propName, out dpOrPi, out declaringType);
// Check if the value is a MarkupExtension. If so it must be expanded into
// a series of baml records. Otherwise just write out the property.
AttributeData data = _extensionParser.IsMarkupExtensionAttribute(
declaringType,
propName,
ref value,
0, // No line numbers for baml
0,
0,
dpOrPi);View on GitHub (pinned to 81131a70a4)