dotnet/wpf · error
SR.Format(SR.BamlWriterBadScope, startTagState.ToString()…
Error message
SR.Format(SR.BamlWriterBadScope, startTagState.ToString(), endTagBeingWritten.ToString())
What it means
BamlWriter tracks a scope stack of opened BAML records (elements, properties, constructors). VerifyEndTagState pops the stack and, when the record on top does not match the tag kind currently being closed, throws InvalidOperationException('Bad scope'). It signals a mismatch between the write calls made and the structure of the BAML document being produced.
Solutions
- Ensure every WriteStartElement/WriteEndElement/WriteStartConstructor/WriteEndConstructor call is properly paired and nested
- Check that WriteEndDocument is only called after all open scopes are closed
- If wrapping BamlWriter, mirror all calls one-to-one to the underlying writer
- Debug the scope mismatch by logging each Push/Pop (start/end) call sequence before the throw
Example fix
// before writer.WriteStartElement(elementType); writer.WriteStartConstructor(); writer.WriteEndElement(); // bad scope: constructor still open // after writer.WriteStartElement(elementType); writer.WriteStartConstructor(); writer.WriteEndConstructor(); writer.WriteEndElement();
Defensive patterns
Strategy: try-catch
Validate before calling
if (openScopes.Count == 0 || openScopes.Peek() != expectedStartTag) throw new InvalidOperationException("Unbalanced BamlWriter scope: cannot close " + endTagBeingWritten); Type guard
bool CanClose(BamlWriter w, BamlRecordType expected) => openScopes.Count > 0 && openScopes.Peek() == expected;
Try / catch
try { writer.WriteEndElement(); } catch (InvalidOperationException ex) when (ex.Message.Contains("scope")) { LogUnbalancedScope(ex); throw; } Prevention
- Pair every start/end write call in a using/finally discipline
- Track the scope stack yourself and assert before closing
- Never call WriteEndDocument with open element or constructor scopes
When it happens
Trigger: Calling BamlWriter.WriteEndElement, WriteEndConstructor, or WriteEndDocument when the innermost open record is of a different kind (e.g. WriteEndElement while a constructor or property record is on the stack, or closing elements out of order).
Common situations: Custom markup writers or serializers hand-building BAML streams; buggy code that interleaves WriteStartElement/WriteEndElement pairs incorrectly; calling WriteEndDocument while elements are still open or vice versa.
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
- Can't Assign to Known Type attributes
- Cannot reopen a popup in the closed event handler.
- Could not find prefix for type
- Found unexpected Xmlns BAML record
- InvalidOperationException(SR.Format(SR.XamlXmlWriterWriteNot…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/42bc4c0c6417be58.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlWriter.cs:1043
*
* BamlWriter.VerifyEndTagState
*
* Verify that we are in a good state to perform a record write and that
* the xamlnodetype on the node type stack is of the expected type. This
* is called when an end tag record is written
*
\***************************************************************************/
private void VerifyEndTagState(
BamlRecordType expectedStartTag,
BamlRecordType endTagBeingWritten)
{
VerifyWriteState();
BamlRecordType startTagState = Pop();
if (startTagState != expectedStartTag)
{
throw new InvalidOperationException(SR.Format(SR.BamlWriterBadScope,
startTagState.ToString(),
endTagBeingWritten.ToString()));
}
}
/***************************************************************************\
*
* BamlWriter.GetAssembly
*
* Get the Assembly given a name. This uses the LoadWrapper to load the
* assembly from the current directory.
* NOTE: Assembly paths are not currently supported, but may be in the
* future if the need arises.
*
\***************************************************************************/
private Assembly GetAssembly(string assemblyName)
{View on GitHub (pinned to 81131a70a4)