dotnet/wpf · error · InvalidOperationException
SR.BamlWriterStartDoc
Error message
SR.BamlWriterStartDoc
What it means
BamlWriter.WriteStartDocument throws this InvalidOperationException when WriteStartDocument is called a second time. BAML output must begin with exactly one document-start record, so the writer tracks _startDocumentWritten and rejects duplicate calls. It is a caller sequencing bug, not a data problem.
Solutions
- Call WriteStartDocument at most once per BamlWriter instance; guard with a flag or assert before calling.
- If retrying serialization after failure, create a new BamlWriter (and underlying stream) instead of restarting the old one.
- Check for duplicate Serialize entry points (e.g. both an explicit WriteStartDocument and a Serialize call that writes it).
Example fix
// before writer.WriteStartDocument(); Serialize(writer, obj); // Serialize also writes start document // after Serialize(writer, obj); // let Serialize own the document lifecycle
Defensive patterns
Strategy: validation
Validate before calling
bool startDocWritten = false;
void SafeWriteStartDocument(BamlWriter w)
{
if (!startDocWritten) { w.WriteStartDocument(); startDocWritten = true; }
} Try / catch
try { writer.WriteStartDocument(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("start document")) { /* already started; ignore */ } Prevention
- Let Serialize own WriteStartDocument; never call it manually alongside Serialize.
- Recreate BamlWriter per serialization attempt instead of restarting a used one.
- Assert document lifecycle invariants in debug builds.
When it happens
Trigger: Calling WriteStartDocument() twice on the same BamlWriter instance, e.g. calling it again after an exception-and-retry inside Serialize, or reusing a writer object believed to be fresh.
Common situations: Wrapping Serialize in retry logic that restarts mid-stream without recreating the BamlWriter; copying sample code that calls WriteStartDocument when the serializer already did; accidental double invocation in custom serialization loops.
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.BamlWriterNoInElement
- SR.BamlBadExtensionValue
- SR.BamlWriterUnknownMarkupExtension
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/322e5ab8cea887c4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlWriter.cs:149
#region Record Writing
/// <summary>
/// Write the start of document record, giving the baml version string
/// </summary>
/// <remarks>
/// This must be the first call made when creating a new baml file. This
/// is needed to specify the start of the document and baml version.
/// </remarks>
public void WriteStartDocument()
{
if (_closed)
{
throw new InvalidOperationException(SR.BamlWriterClosed);
}
if (_startDocumentWritten)
{
throw new InvalidOperationException(SR.BamlWriterStartDoc);
}
XamlDocumentStartNode node = new XamlDocumentStartNode(0,0,_depth);
_bamlRecordWriter.WriteDocumentStart(node);
_startDocumentWritten = true;
Push(BamlRecordType.DocumentStart);
}
/// <summary>
/// Write the end of document record.
/// </summary>
/// <remarks>
/// This must be the last call made when creating a new baml file.
/// </remarks>
public void WriteEndDocument()
{
VerifyEndTagState(BamlRecordType.DocumentStart,
BamlRecordType.DocumentEnd);View on GitHub (pinned to 81131a70a4)