{"record":{"id":"90737604392f2db5","repo":"rocksdanister/lively","slug":"corrupted-wallpaper-metadata","errorCode":null,"errorMessage":"Corrupted wallpaper metadata","messagePattern":"Corrupted wallpaper metadata","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"src/Lively/Lively.Common/Factories/WallpaperLibraryFactory.cs","lineNumber":21,"sourceCode":"using Lively.Common.Helpers.Shell;\nusing Lively.Common.Helpers.Storage;\nusing Lively.Models;\nusing Lively.Models.Enums;\nusing System;\nusing System.Drawing.Imaging;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace Lively.Common.Factories\n{\n    public class WallpaperLibraryFactory : IWallpaperLibraryFactory\n    {\n        public LivelyInfoModel GetMetadata(string folderPath)\n        {\n            if (!File.Exists(Path.Combine(folderPath, \"LivelyInfo.json\")))\n                throw new FileNotFoundException(\"LivelyInfo.json not found\");\n\n            return JsonStorage<LivelyInfoModel>.LoadData(Path.Combine(folderPath, \"LivelyInfo.json\")) ?? throw new FileNotFoundException(\"Corrupted wallpaper metadata\");\n        }\n\n        public LibraryModel CreateFromDirectory(string folderPath)\n        {\n            var metadata = GetMetadata(folderPath);\n            var result = new LibraryModel\n            {\n                LivelyInfo = metadata,\n                LivelyInfoFolderPath = folderPath,\n                LivelyInfoLocalizationPath = Path.Combine(folderPath, \"LivelyInfo.loc.json\"),\n                LivelyPropertyLocalizationPath = Path.Combine(folderPath, \"LivelyProperties.loc.json\"),\n                IsSubscribed = !string.IsNullOrEmpty(metadata.Id),\n                Title = metadata.Title,\n                Desc = metadata.Desc,\n                Author = metadata.Author\n            };\n            if (metadata.IsAbsolutePath)\n            {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/rocksdanister/lively/blob/c1036feb664960722e34bf4309042c247d6a909d/src/Lively/Lively.Common/Factories/WallpaperLibraryFactory.cs#L3-L39","documentation":"Thrown by GetMetadata when LivelyInfo.json exists but JsonStorage<LivelyInfoModel>.LoadData returns null, i.e. the JSON deserialised to null because it is empty, malformed, or does not match LivelyInfoModel. Note the exception TYPE is FileNotFoundException even though the cause is corruption — a leaky abstraction worth flagging.","triggerScenarios":"LivelyInfo.json present but empty, truncated, syntactically invalid JSON, or a schema that does not bind to LivelyInfoModel (missing required fields, wrong type). The null-coalesce `?? throw` fires when the deserializer yields null.","commonSituations":"User hand-edited the manifest and broke it; a half-written file from a crashed save; version skew where an older/newer LivelyInfoModel shape no longer matches the file; encoding issues (BOM/UTF-16) confusing Newtonsoft.Json.","solutions":["Open LivelyInfo.json and validate it parses against the LivelyInfoModel schema (check required fields: Title, Type, FileName, etc.).","Restore the manifest from a backup or re-package the wallpaper with CreateWallpaperPackage.","Catch FileNotFoundException around GetMetadata and surface a 'corrupt wallpaper, re-import' message to the user rather than crashing.","If maintaining the library, throw a more accurate exception type (e.g. InvalidDataException) so callers can distinguish missing-vs-corrupt."],"exampleFix":"// before\nreturn JsonStorage<LivelyInfoModel>.LoadData(path) ?? throw new FileNotFoundException(\"Corrupted wallpaper metadata\");\n\n// after (distinguish corrupt from missing, accurate type)\nLivelyInfoModel tmp;\ntry { tmp = JsonStorage<LivelyInfoModel>.LoadData(path); }\ncatch (Exception ex) { throw new InvalidDataException(\"LivelyInfo.json is not valid JSON\", ex); }\nreturn tmp ?? throw new InvalidDataException(\"LivelyInfo.json deserialised to null\");","handlingStrategy":"try-catch","validationCode":"var json = File.ReadAllText(manifestPath);\nif (string.IsNullOrWhiteSpace(json))\n    throw new InvalidDataException(\"LivelyInfo.json is empty\");\nJsonConvert.DeserializeObject<LivelyInfoModel>(json); // throws JsonException on malformed","typeGuard":"static bool TryParseManifest(string path, out LivelyInfoModel model)\n{\n    model = default;\n    try { model = JsonConvert.DeserializeObject<LivelyInfoModel>(File.ReadAllText(path)); }\n    catch { return false; }\n    return model != null;\n}","tryCatchPattern":"try { meta = factory.GetMetadata(folderPath); }\ncatch (FileNotFoundException ex) when (ex.Message.Contains(\"Corrupted\"))\n{\n    // offer to re-import / restore from backup\n}","preventionTips":["Never hand-edit LivelyInfo.json; use the packaging tooling.","Treat missing-vs-corrupt as distinct cases (the exception type is misleading — match on message or validate first).","Back up manifests before migration/export."],"tags":["json","deserialization","metadata","wallpaper","schema"],"backgroundTag":null,"analyzedSha":"c1036feb664960722e34bf4309042c247d6a909d","analyzedAt":"2026-08-13T13:03:12.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}