dotnet/wpf · error · InvalidOperationException

SR.BamlScopeError

Error message

SR.BamlScopeError: {0} {1}

What it means

BamlReader.ReadDocumentEndRecord pops the node stack expecting the matching DocumentStart record. If the popped node is anything else, the BAML stream's start/end records are unbalanced and the reader throws InvalidOperationException with SR.BamlScopeError, naming the unexpected record type and "DocumentEnd".

Solutions

  1. Regenerate the BAML by rebuilding the project — the stream is likely corrupt or hand-modified.
  2. Ensure every Read call sequence consumes all records (do not abandon reads mid-stream and reuse the reader).
  3. If generating BAML yourself, verify every DocumentStart/ElementStart record has its matching end record in order.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify balanced document scope by walking records before reading
int depth = 0;
foreach (var r in records) {
    if (r.RecordType == BamlRecordType.DocumentStart) depth++;
    if (r.RecordType == BamlRecordType.DocumentEnd && --depth != 0)
        throw new InvalidOperationException("Unbalanced DocumentStart/DocumentEnd in BAML.");
}

Type guard

bool DocumentScopeBalanced(IEnumerable<BamlRecord> recs) => recs.Count(r => r.RecordType == BamlRecordType.DocumentStart) == recs.Count(r => r.RecordType == BamlRecordType.DocumentEnd);

Try / catch

try { reader.Read(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DocumentEnd")) {
    log.LogError("Unbalanced BAML document scope — regenerate the BAML resource.");
}

Prevention

When it happens

Trigger: Calling ReadDocumentEndRecord (via Read when the stream yields a DocumentEnd record) while the top of _nodeStack is not BamlRecordType.DocumentStart — e.g. elements or properties were opened but never closed before the document end record.

Common situations: Corrupted or truncated BAML resource; a BAML stream assembled by custom tooling with mismatched start/end records; interrupting a read loop so records are skipped and the stack gets out of sync.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/9445131999b07193. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlReader.cs:1851

        }

        /***************************************************************************\
        *
        * BamlReader.ReadDocumentEndRecord
        *
        * Read the end of the document record.  This is used to flag that the end
        * of the file has been reached.
        *
        \***************************************************************************/

        private void ReadDocumentEndRecord()
        {
            // Pop information off the node stack to ensure we have matched all the
            // start and end nodes and have nothing left but the start document node.
            BamlNodeInfo nodeInfo = _nodeStack.Pop();
            if (nodeInfo.RecordType != BamlRecordType.DocumentStart)
            {
                throw new InvalidOperationException(SR.Format(SR.BamlScopeError,
                                                    nodeInfo.RecordType.ToString(),
                                                    "DocumentEnd"));
            }

            ClearProperties();
            NodeTypeInternal = BamlNodeType.EndDocument;
        }

        private void ReadAssemblyInfoRecord()
        {
            BamlAssemblyInfoRecord asmRecord = (BamlAssemblyInfoRecord)_currentBamlRecord;
            MapTable.LoadAssemblyInfoRecord(asmRecord);

            Assembly asm = Assembly.Load(asmRecord.AssemblyFullName);
            foreach (XmlnsDefinitionAttribute xmlnsDef in asm.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), true))
            {
                SetXmlNamespace(xmlnsDef.ClrNamespace, asm.FullName, xmlnsDef.XmlNamespace);
            }

View on GitHub (pinned to 81131a70a4)