dotnet/wpf · error · InvalidOperationException
SR.ParserMultiBamls
Error message
SR.ParserMultiBamls
What it means
BamlRecords' SetWriteCache (used by GetPropertyStartRecordType record management) throws InvalidOperationException(SR.ParserMultiBamls) when a BamlRecord that is not pinned is written to a cache slot that already holds a record — the write-cache assumes each record type appears once. The Debug.Assert shows this is an internal invariant; the throw is the release-mode fallback.
Solutions
- Use a fresh BamlRecordManager/writer per document; do not share record caches across BAML streams
- Ensure each record is Pinned before reuse across multiple writes
- This is framework-internal — if hit via public APIs, file a bug with a minimal XAML-to-BAML repro
- Check for reentrancy: nested/concurrent serialization using the same writer
Example fix
// before: shared record manager across documents var rm = new BamlRecordManager(); WriteBaml(doc1, rm); WriteBaml(doc2, rm); // after: one manager per document WriteBaml(doc1, new BamlRecordManager()); WriteBaml(doc2, new BamlRecordManager());
Defensive patterns
Strategy: validation
Validate before calling
// never share a BamlRecordManager/writer across documents
if (recordManager.InUse) throw new InvalidOperationException("Record manager already in use for another BAML"); Try / catch
try { WriteBaml(doc, recordManager); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Baml")) {
recordManager = new BamlRecordManager(); // recreate and retry once
} Prevention
- One record manager per BAML document
- No concurrent serialization on shared caches
- Pin records before cross-document reuse
When it happens
Trigger: BAML writer/record-manager encounters a second non-pinned record of the same RecordType while the cache slot is still occupied — during multi-BAML assembly/serialization bookkeeping.
Common situations: Writing multiple BAML documents concurrently or sequentially through shared record caches, framework-internal record-manager misuse, or custom tooling that reuses BamlRecordManager across documents without clearing it.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- SR.BamlWriterClosed
- Can't Assign to Known Type attributes
- Could not find prefix for type
- Found unexpected Xmlns BAML record
- NotImplementedException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/1877dc32a71e906d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecords.cs:769
// ReleaseWriteRecord
//
// Frees a record originally claimed with GetWriteRecord. Note that records in the
// read cache are implicitly recycled, and records in the write cache are explicitly
// recycled (i.e., there's a ReleaseWriteRecord, but no ReleaseReadRecord).
//
//+---------------------------------------------------------------------------------------------
internal void ReleaseWriteRecord(BamlRecord record)
{
// Put the write record back into the cache, if we're allowed to recycle it.
if( !record.IsPinned )
{
Debug.Assert(null == _writeCache[(int)record.RecordType]);
if (null != _writeCache[(int)record.RecordType])
{
// This is really an internal error.
throw new InvalidOperationException(SR.ParserMultiBamls);
}
_writeCache[(int)record.RecordType] = record;
}
}
// Cache of BamlRecords, used during read, to avoid lots of records from being
// created. If a record gets pinned (BamlRecord.IsPinned gets set), it is not re-used.
#if !PBTCOMPILER
private BamlRecord[] _readCache = new BamlRecord[(int)BamlRecordType.LastRecordType];
#endif
// Cache of BamlRecords, used during write, also to avoid lots of records
// from being created.
private BamlRecord[] _writeCache = null; //new BamlRecord[(int)BamlRecordType.LastRecordType];
}View on GitHub (pinned to 81131a70a4)