{"record":{"id":"318811c05cc6845e","repo":"dotnet/wpf","slug":"sr-bamlreaderclosed","errorCode":null,"errorMessage":"SR.BamlReaderClosed","messagePattern":"SR\\.BamlReaderClosed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlReader.cs","lineNumber":316,"sourceCode":"        public string TypeConverterName\n        {\n            get { return _typeConverterName; }\n        }\n\n        public string TypeConverterAssemblyName\n        {\n            get { return _typeConverterAssemblyName; }\n        }\n\n        /// <summary>\n        /// Reads the next node from the stream.\n        /// </summary>\n        public bool Read()\n        {\n            if (_readState == ReadState.EndOfFile ||\n                _readState == ReadState.Closed)\n            {\n                throw new InvalidOperationException(SR.BamlReaderClosed);\n            }\n\n            ReadNextRecord();\n\n            return _readState != ReadState.EndOfFile;\n        }\n\n        private BamlNodeType NodeTypeInternal\n        {\n            set { _bamlNodeType = value; }\n        }\n\n        private void AddToPropertyInfoCollection(object info)\n        {\n            _properties.Add(info);\n        }\n\n        /// <summary>","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlReader.cs#L298-L334","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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();`"],"exampleFix":"// before\nreader.Read(); ProcessCurrent(reader); reader.Read(); ProcessCurrent(reader); // throws after EOF\n// after\nwhile (reader.Read()) { ProcessCurrent(reader); }","handlingStrategy":"try-catch","validationCode":"if (reader.ReadState == ReadState.Closed || reader.ReadState == ReadState.EndOfFile)\n    reader = CreateNewReader();","typeGuard":"bool CanRead(BamlReader r) => r.ReadState != ReadState.Closed && r.ReadState != ReadState.EndOfFile;","tryCatchPattern":"try { more = reader.Read(); }\ncatch (InvalidOperationException) when (reader.ReadState == ReadState.Closed)\n{\n    reader = CreateNewReader(); more = reader.Read();\n}","preventionTips":["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."],"tags":["wpf","baml","reader","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}