{"record":{"id":"c178f06b386f2f40","repo":"AutoDarkMode/Windows-Auto-Night-Mode","slug":"failed-to-deserialize-json-from-file-path","errorCode":null,"errorMessage":"Failed to deserialize JSON from file: {path}","messagePattern":"Failed to deserialize JSON from file: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"AutoDarkModeApp/Services/FileService.cs","lineNumber":37,"sourceCode":"        var path = Path.Combine(folderPath, fileName);\n        if (!File.Exists(path))\n        {\n            return default;\n        }\n\n        var json = File.ReadAllText(path);\n        if (string.IsNullOrWhiteSpace(json))\n        {\n            return default;\n        }\n\n        try\n        {\n            return JsonSerializer.Deserialize<T>(json, _jsonOptions);\n        }\n        catch (JsonException ex)\n        {\n            throw new InvalidOperationException($\"Failed to deserialize JSON from file: {path}\", ex);\n        }\n    }\n\n    public void Save<T>(string folderPath, string fileName, T content)\n    {\n        if (!Directory.Exists(folderPath))\n        {\n            Directory.CreateDirectory(folderPath);\n        }\n\n        var fileContent = JsonSerializer.Serialize(content, _jsonOptions);\n        WriteAllTextWithRetry(Path.Combine(folderPath, fileName), fileContent);\n    }\n\n    public void Delete(string folderPath, string fileName)\n    {\n        if (fileName != null && File.Exists(Path.Combine(folderPath, fileName)))\n        {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/AutoDarkMode/Windows-Auto-Night-Mode/blob/c15b28e92138a1baff6165bbca80842f06cb819f/AutoDarkModeApp/Services/FileService.cs#L19-L55","documentation":"Thrown by FileService.Read<T>() when System.Text.Json cannot parse the contents of a local settings file. The method reads the file with File.ReadAllText, checks for blank content (returns default), then attempts JsonSerializer.Deserialize; any JsonException is caught and re-thrown as InvalidOperationException with the file path as context. It signals that a persisted JSON file exists but is syntactically invalid or does not match the target type T.","triggerScenarios":"Calling IFileService.Read<T>(folderPath, fileName) where the file at Path.Combine(folderPath, fileName) contains malformed JSON (truncated, invalid syntax, wrong types). The JsonSerializer.Deserialize<T> call throws JsonException which is wrapped at FileService.cs:37.","commonSituations":"App crash or power loss during Save() truncates a settings JSON file; antivirus or sync tools (OneDrive) lock and partially rewrite the file; a user manually edits a settings file and introduces a syntax error; an app upgrade changed the type T so an old file no longer deserializes cleanly.","solutions":["Open the file at the reported {path} and validate its JSON (e.g. with a linter); fix or delete it so the app regenerates defaults.","Delete the corrupt file entirely — Read<T> returns default when the file is absent, letting the app rebuild it.","Ensure Save() writes atomically (write to a temp file then File.Move/replace) to prevent partial writes from crashes.","Verify the file encoding is UTF-8 without BOM issues and that the JSON matches the current type T schema after upgrades."],"exampleFix":"// before (FileService.Save — non-atomic, truncates on crash)\nvar fileContent = JsonSerializer.Serialize(content, _jsonOptions);\nWriteAllTextWithRetry(Path.Combine(folderPath, fileName), fileContent);\n\n// after — write temp then atomic move so a crash cannot leave a truncated file\nvar temp = Path.Combine(folderPath, fileName + \".tmp\");\nFile.WriteAllText(temp, fileContent, Encoding.UTF8);\nif (File.Exists(path)) File.Replace(temp, path, null);\nelse File.Move(temp, path);","handlingStrategy":"try-catch","validationCode":"// Pre-validate the file is parseable JSON before deserializing into T\npublic static bool TryValidateJson(string path)\n{\n    if (!File.Exists(path)) return true; // absent is fine, Read returns default\n    var json = File.ReadAllText(path);\n    if (string.IsNullOrWhiteSpace(json)) return true;\n    try { using var doc = JsonDocument.Parse(json); return true; }\n    catch (JsonException) { return false; }\n}","typeGuard":"// Type guard for callers of FileService.Read<T>\nif (fileService.Read<MySettings>(folder, file) is { } settings)\n{\n    // settings deserialized successfully\n}\nelse\n{\n    // file missing, blank, or returned default — apply defaults\n}","tryCatchPattern":"try\n{\n    var settings = fileService.Read<MySettings>(folder, file);\n}\ncatch (InvalidOperationException ex) when (ex.InnerException is JsonException)\n{\n    // corrupt settings file — back it up and let the app regenerate defaults\n    File.Move(path, path + \".corrupt\");\n}","preventionTips":["Write settings atomically (temp file + File.Replace) so a crash cannot leave a truncated JSON file.","Exclude the settings directory from AV/cloud-sync real-time scanning that can lock or partially rewrite files.","After an app upgrade that changes type T, add a migration/version field so old files deserialize or are reset cleanly.","Never hand-edit settings JSON; if you must, validate with a JSON linter before saving."],"tags":["json","deserialization","configuration","file-io","system-text-json"],"backgroundTag":null,"analyzedSha":"c15b28e92138a1baff6165bbca80842f06cb819f","analyzedAt":"2026-08-13T21:04:56.049Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}