{"record":{"id":"be31478575a3d72a","repo":"subhra74/xdm","slug":"unable-to-read-state","errorCode":null,"errorMessage":"Unable to read state: ","messagePattern":"Unable to read state: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/XDM/XDM.Core/IO/DownloadStateIO.cs","lineNumber":72,"sourceCode":"#if NET35\r\n                ms.CopyTo(stream);\r\n#endif\r\n            });\r\n        }\r\n    }\r\n\r\n    public static class DownloadStateIO\r\n    {\r\n        public static SingleSourceHTTPDownloaderState LoadSingleSourceHTTPDownloaderState(string id)\r\n        {\r\n            SingleSourceHTTPDownloaderState? state = null;\r\n            TransactedBinaryDataReader.Read($\"{id}.state\", Config.DataDir, r =>\r\n            {\r\n                state = SingleSourceHTTPDownloaderStateFromBytes(r);\r\n            });\r\n            if (state == null)\r\n            {\r\n                throw new IOException(\"Unable to read state: \" + id);\r\n            }\r\n            return state;\r\n        }\r\n\r\n        private static SingleSourceHTTPDownloaderState SingleSourceHTTPDownloaderStateFromBytes(BinaryReader r)\r\n        {\r\n            var state = new SingleSourceHTTPDownloaderState\r\n            {\r\n                Id = r.ReadString(),\r\n                TempDir = XDM.Messaging.StreamHelper.ReadString(r),\r\n                FileSize = r.ReadInt64(),\r\n                LastModified = DateTime.FromBinary(r.ReadInt64()),\r\n                SpeedLimit = r.ReadInt32(),\r\n                Url = new Uri(r.ReadString())\r\n            };\r\n            if (r.ReadBoolean())\r\n            {\r\n                XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);\r","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/subhra74/xdm/blob/1ca5a25aae007826c859c81bea494e7c102e1242/app/XDM/XDM.Core/IO/DownloadStateIO.cs#L54-L90","documentation":"DownloadStateIO.LoadSingleSourceHTTPDownloaderState throws IOException(\"Unable to read state: <id>\") when TransactedBinaryDataReader.Read completed but the deserializer (SingleSourceHTTPDownloaderStateFromBytes) produced a null state. This means the <id>.state file in Config.DataDir exists (or a transaction left no usable data) but could not yield a valid SingleSourceHTTPDownloaderState object — typically a corrupt, empty, or format-incompatible state file.","triggerScenarios":"Calling DownloadStateIO.LoadSingleSourceHTTPDownloaderState(id) where the <id>.state file is empty, truncated, corrupted, or written by an incompatible binary format version, so SingleSourceHTTPDownloaderStateFromBytes returns null.","commonSituations":"App crash/kill mid-write (mitigated by transacted read but not fully); upgrading XDM across a state-format change; manual copying of state files between machines; disk corruption or partial file sync (Dropbox/OneDrive) of the data directory.","solutions":["Treat the download as unrecoverable: delete <id>.state from Config.DataDir and start the download again.","Back up the file first and inspect its size/contents; an empty or tiny file confirms corruption.","If the file came from another XDM version, restore the state with the matching version or re-create the download.","Check for leftover transaction artifacts in Config.DataDir and restore the last committed state file if present."],"exampleFix":"// before\nvar state = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(id); // throws IOException\n// after\nSingleSourceHTTPDownloaderState state;\ntry { state = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(id); }\ncatch (IOException)\n{\n    DownloadStateIO.DeleteState(id); // discard corrupt state\n    state = null; // fall back to starting a fresh download\n}","handlingStrategy":"try-catch","validationCode":"var path = Path.Combine(Config.DataDir, id + \".state\");\nif (!File.Exists(path) || new FileInfo(path).Length == 0)\n{\n    // state missing or empty — do not attempt load; start a fresh download\n}","typeGuard":"static bool StateFileLooksValid(string dataDir, string id)\n{\n    var p = Path.Combine(dataDir, id + \".state\");\n    try { return File.Exists(p) && new FileInfo(p).Length > 0; }\n    catch (IOException) { return false; }\n}","tryCatchPattern":"SingleSourceHTTPDownloaderState state;\ntry { state = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(id); }\ncatch (IOException ex)\n{\n    Log.Debug(ex, $\"corrupt state {id}\");\n    DownloadStateIO.DeleteState(id);\n    state = null; // fall back to a fresh download\n}","preventionTips":["Shut down the app gracefully so state transactions commit.","Back up Config.DataDir periodically if download resumability matters.","Keep the same XDM version for writing and reading state files.","Exclude Config.DataDir from cloud sync and antivirus to avoid truncation."],"tags":["io","state-persistence","deserialization","corrupt-file"],"backgroundTag":"file-read-failed","analyzedSha":"1ca5a25aae007826c859c81bea494e7c102e1242","analyzedAt":"2026-09-13T20:37:40.968Z","contentChangedAt":"2026-09-13T20:37:40.968Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}