{"record":{"id":"a2e8e2526bf04d51","repo":"rocksdanister/lively","slug":"json-null-corrupt","errorCode":null,"errorMessage":"json null/corrupt","messagePattern":"json null/corrupt","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Lively/Lively.Common/Helpers/Storage/JsonStorage.cs","lineNumber":20,"sourceCode":"using System.IO;\nusing Newtonsoft.Json;\n\nnamespace Lively.Common.Helpers.Storage\n{\n    public static class JsonStorage<T>\n    {\n        public static T LoadData(string filePath)\n        {\n            // deserialize JSON directly from a file\n            using StreamReader file = File.OpenText(filePath);\n            var serializer = new JsonSerializer\n            {\n                //TypeNameHandling = TypeNameHandling.Auto\n            };\n            var tmp = (T)serializer.Deserialize(file, typeof(T));\n\n            //if file is corrupted, json can return null.\n            return (tmp != null ? tmp : throw new ArgumentNullException(\"json null/corrupt\"));\n        }\n\n        public static void StoreData(string filePath, T data)\n        {\n            JsonSerializer serializer = new JsonSerializer\n            {\n                Formatting = Formatting.Indented,\n                //serializer.Converters.Add(new JavaScriptDateTimeConverter());\n                NullValueHandling = NullValueHandling.Include,\n                //TypeNameHandling = TypeNameHandling.Auto,\n            };\n\n            using StreamWriter sw = new StreamWriter(filePath);\n            using JsonWriter writer = new JsonTextWriter(sw);\n            serializer.Serialize(writer, data, typeof(T));\n        }\n    }\n}","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/rocksdanister/lively/blob/c1036feb664960722e34bf4309042c247d6a909d/src/Lively/Lively.Common/Helpers/Storage/JsonStorage.cs#L2-L38","documentation":"Thrown by the generic JsonStorage<T>.LoadData when Newtonsoft.Json deserialises the file to null. This loader backs most on-disk config/metadata in Lively, so the message is generic. Note the exception TYPE is ArgumentNullException with a message string as paramName — the type does not match the failure (corruption, not a null argument).","triggerScenarios":"Any JsonStorage<T>.LoadData(filePath) where the file is empty, contains JSON that deserialises to null (e.g. literal \"null\", or an empty object for a non-nullable reference type that the converter leaves null), or the type T cannot be bound from the content.","commonSituations":"Empty settings file left by a failed write or reset; hand-edited config that became invalid; upgrade/downgrade where T's shape changed; files with content \"null\" from a previous bug; encoding/BOM issues.","solutions":["Open the file and confirm it is non-empty, valid JSON matching T's schema.","Delete or back up the offending file so the app regenerates defaults on next start.","Wrap LoadData in try/catch and fall back to default(T) / a fresh settings instance, logging the corruption.","If maintaining the lib, replace the throw with a typed JsonException/InvalidDataException and pass the file path for diagnostics."],"exampleFix":"// before\nreturn (tmp != null ? tmp : throw new ArgumentNullException(\"json null/corrupt\"));\n\n// after\nreturn tmp ?? throw new JsonException($\"{filePath} deserialised to null (empty or wrong schema for {typeof(T).Name})\");","handlingStrategy":"try-catch","validationCode":"if (!File.Exists(filePath) || new FileInfo(filePath).Length == 0)\n    return default(T); // or regenerate defaults\nvar json = File.ReadAllText(filePath);\nif (string.IsNullOrWhiteSpace(json) || json.Trim() == \"null\") return default(T);","typeGuard":"static bool TryLoad<T>(string path, out T value)\n{\n    value = default;\n    try { value = JsonStorage<T>.LoadData(path); return value != null; }\n    catch { return false; }\n}","tryCatchPattern":"T cfg;\ntry { cfg = JsonStorage<T>.LoadData(path); }\ncatch (ArgumentNullException ex) when (ex.ParamName?.Contains(\"json null\") == true)\n{ cfg = DefaultT(); /* reset to defaults and persist */ }","preventionTips":["Write settings atomically (temp file + rename) to avoid empty/corrupt files.","Back up config before schema migrations.","Treat load failure as 'reset to defaults' rather than crash for non-critical state."],"tags":["json","deserialization","storage","config","schema"],"backgroundTag":null,"analyzedSha":"c1036feb664960722e34bf4309042c247d6a909d","analyzedAt":"2026-08-13T13:03:12.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}