{"record":{"id":"56304b674484accf","repo":"BCUninstaller/Bulk-Crap-Uninstaller","slug":"the-uninstall-list-file-is-empty","errorCode":null,"errorMessage":"The uninstall list file is empty.","messagePattern":"The uninstall list file is empty\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"source/UninstallTools/Lists/UninstallList.cs","lineNumber":93,"sourceCode":"            }\r\n\r\n            if (!included.HasValue)\r\n                return excluded.HasValue ? true : null;\r\n            return included.Value;\r\n        }\r\n\r\n        public bool Enabled { get; set; } = true;\n\n        public static UninstallList ReadFromFile(string fileName)\n        {\n            if (string.IsNullOrWhiteSpace(fileName))\n                throw new ArgumentException(\"File name cannot be empty.\", nameof(fileName));\n\n            var serializer = new XmlSerializer(typeof (UninstallList));\n            using (var stream = File.OpenRead(fileName))\n            {\n                if (stream.Length == 0)\n                    throw new InvalidDataException(\"The uninstall list file is empty.\");\n\n                try\n                {\n                    return Deserialize(serializer, XmlReader.Create(stream, ReaderSettings));\n                }\n                catch (Exception ex) when (ex is InvalidOperationException or XmlException)\n                {\n                    if (!stream.CanSeek)\n                        throw CreateInvalidDataException(ex);\n\n                    stream.Position = 0;\n                    using var textReader = new StreamReader(stream, Encoding.UTF8, true, 1024, true);\n                    var trimmedContents = textReader.ReadToEnd().TrimStart('\\uFEFF', '\\u200B', ' ', '\\t', '\\r', '\\n');\n                    if (trimmedContents.Length == 0)\n                        throw CreateInvalidDataException(ex);\n\n                    using var stringReader = new StringReader(trimmedContents);\n                    try","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/BCUninstaller/Bulk-Crap-Uninstaller/blob/608321de98e92297377b1eb69029af55c25504a1/source/UninstallTools/Lists/UninstallList.cs#L75-L111","documentation":"After opening the file for read, ReadFromFile checks stream.Length == 0 and throws InvalidDataException 'The uninstall list file is empty.' An empty file would cause the XmlSerializer to throw a generic InvalidOperationException; the explicit length check produces a meaningful, user-presentable error before deserialisation.","triggerScenarios":"Pointing ReadFromFile at a zero-byte file: a truncated download, a file created by 'touch' or an interrupted save, or a placeholder file written by another tool.","commonSituations":"An uninstall list file was partially written and the process crashed leaving a 0-byte file; a sync/cloud client has not finished downloading the file; antivirus quarantined and emptied the file.","solutions":["Check new FileInfo(fileName).Length > 0 before calling ReadFromFile and prompt the user.","Restore from a backup (.bak) if the file is unexpectedly empty.","Ensure the writer's save path opens with FileShare.None and writes atomically (write to .tmp then File.Move) so an interrupted save never leaves a 0-byte target."],"exampleFix":"// before\nvar list = UninstallList.ReadFromFile(path);\n\n// after\nif (new FileInfo(path).Length == 0)\n    throw new InvalidDataException($\"'{path}' is empty; the save may have been interrupted.\");\nvar list = UninstallList.ReadFromFile(path);","handlingStrategy":"validation","validationCode":"var info = new FileInfo(fileName);\nif (!info.Exists || info.Length == 0)\n    throw new InvalidDataException($\"'{fileName}' is missing or empty.\");\nvar list = UninstallList.ReadFromFile(fileName);","typeGuard":"null","tryCatchPattern":"try { list = UninstallList.ReadFromFile(path); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"empty\"))\n{\n    list = RestoreFromBackup(path);\n}","preventionTips":["Write list files atomically (temp file + File.Move) so an interrupted save never leaves a 0-byte file.","Keep a .bak copy of the previous list and restore on empty-file errors.","Confirm cloud-sync clients have finished downloading before opening."],"tags":["io","invalid-data","uninstall-list","file-empty","deserialisation"],"backgroundTag":null,"analyzedSha":"608321de98e92297377b1eb69029af55c25504a1","analyzedAt":"2026-08-13T12:17:35.389Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}