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

  1. Only call Read() while it returns true: `while (reader.Read()) { ... }`.
  2. Create a new BamlReader (re-open the stream) instead of reusing a closed/exhausted one.
  3. Track ReadState and reset/recreate the reader if you must re-parse.
  4. 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

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


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)