dotnet/wpf · error · InvalidOperationException
SR.BamlReaderClosed
Error message
SR.BamlReaderClosed
What it means
BamlReader.Read advances the BAML stream to the next record and is only valid while the reader is open and not at end-of-file. If the reader's state is EndOfFile or Closed, it throws InvalidOperationException(SR.BamlReaderClosed) — mirroring XmlReader's contract that a consumed/closed reader cannot be read further.
Solutions
- Only call Read() while it returns true: `while (reader.Read()) { ... }`.
- Create a new BamlReader (re-open the stream) instead of reusing a closed/exhausted one.
- Track ReadState and reset/recreate the reader if you must re-parse.
- Guard with a state check: `if (reader.ReadState != ReadState.Interactive) reader = CreateReader();`
Example fix
// before
reader.Read(); ProcessCurrent(reader); reader.Read(); ProcessCurrent(reader); // throws after EOF
// after
while (reader.Read()) { ProcessCurrent(reader); } Defensive patterns
Strategy: try-catch
Validate before calling
if (reader.ReadState == ReadState.Closed || reader.ReadState == ReadState.EndOfFile)
reader = CreateNewReader(); Type guard
bool CanRead(BamlReader r) => r.ReadState != ReadState.Closed && r.ReadState != ReadState.EndOfFile;
Try / catch
try { more = reader.Read(); }
catch (InvalidOperationException) when (reader.ReadState == ReadState.Closed)
{
reader = CreateNewReader(); more = reader.Read();
} Prevention
- Use `while (reader.Read())` loops instead of unchecked successive calls.
- Never reuse a BamlReader after Close() or EOF; create a fresh one per parse.
- Check ReadState before reading in multi-consumer scenarios.
When it happens
Trigger: Calling Read() again after Read() already returned false (EndOfFile) or after Close() was called; sharing one BamlReader across two consumers that both try to drain it.
Common situations: Loop code that calls Read() without checking the returned bool before the next iteration; re-parsing with a cached/exhausted reader instead of creating a fresh one; reading after dispose.
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.BamlWriterClosed
- Can't Assign to Known Type attributes
- Could not find prefix for type
- Current DocumentSequence, FixedDocument, or FixedPage not…
- Found unexpected Xmlns BAML record
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/318811c05cc6845e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlReader.cs:316
public string TypeConverterName
{
get { return _typeConverterName; }
}
public string TypeConverterAssemblyName
{
get { return _typeConverterAssemblyName; }
}
/// <summary>
/// Reads the next node from the stream.
/// </summary>
public bool Read()
{
if (_readState == ReadState.EndOfFile ||
_readState == ReadState.Closed)
{
throw new InvalidOperationException(SR.BamlReaderClosed);
}
ReadNextRecord();
return _readState != ReadState.EndOfFile;
}
private BamlNodeType NodeTypeInternal
{
set { _bamlNodeType = value; }
}
private void AddToPropertyInfoCollection(object info)
{
_properties.Add(info);
}
/// <summary>View on GitHub (pinned to 81131a70a4)