{"record":{"id":"feed336219c3ac05","repo":"babalae/better-genshin-impact","slug":"tp-json-deserialization-failed","errorCode":null,"errorMessage":"tp.json deserialization failed","messagePattern":"tp\\.json deserialization failed","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"BetterGenshinImpact/GameTask/Common/Element/Assets/MapLazyAssets.cs","lineNumber":45,"sourceCode":"        { \"璃月\", [270, -666] },\n        { \"稻妻\", [-4400, -3050] },\n        { \"须弥\", [2877, -374] },\n        { \"枫丹\", [4515, 3631] },\n        { \"纳塔\", [8973.5, -1879.1] },\n        { \"挪德卡莱\", [9542.25, 1661.84] },\n        { \"至冬\", [6755.051, 9480.659] }\n    };\n\n    public IReadOnlyDictionary<string, GiTpPosition> DomainPositionMap => _domainPositionMap;\n    public IReadOnlyDictionary<string, GiTpPosition> GoddessPositions => _goddessPositions;\n\n    public IReadOnlyList<string> DomainNameList => _domainNameList;\n    public IReadOnlyDictionary<string, List<GiTpPosition>> CountryToDomains => _countryToDomains;\n\n    private MapLazyAssets()\n    {\n        var json = File.ReadAllText(Global.Absolute(@\"GameTask\\AutoTrackPath\\Assets\\tp.json\"));\n        var worldScenes = Newtonsoft.Json.Linq.JObject.Parse(json)[\"data\"]?.ToObject<List<GiWorldScene>>() ?? throw new Exception(\"tp.json deserialization failed\");\n        ScenesDic = worldScenes.ToDictionary(x => x.MapName, x => x);\n\n\n        // 取出秘境 description=Domain\n        var teyvatTpPositions = ScenesDic[nameof(MapTypes.Teyvat)].Points;\n        foreach (var tp in teyvatTpPositions.Where(tp => tp.Type == \"BlessDomain\" || tp.Type == \"ForgeryDomain\" || tp.Type == \"MasteryDomain\"))\n        {\n            _domainPositionMap[tp.Name!] = tp;\n            _domainNameList.Add(tp.Name!);\n\n            if (!string.IsNullOrEmpty(tp.Country))\n            {\n                if (!_countryToDomains.ContainsKey(tp.Country))\n                {\n                    _countryToDomains[tp.Country] = [];\n                }\n\n                _countryToDomains[tp.Country].Add(tp);","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Element/Assets/MapLazyAssets.cs#L27-L63","documentation":"Thrown as a generic Exception by the MapLazyAssets constructor when Newtonsoft.Json's JObject.Parse(json)[\"data\"] resolves to null and ToObject returns null. This means tp.json either lacks a top-level 'data' key or its value is JSON null. The teleport/dungeon/Goddess position data for the entire map depends on this array, so the singleton cannot be constructed.","triggerScenarios":"tp.json at GameTask/AutoTrackPath/Assets/tp.json is missing the 'data' key, has \"data\": null, or is malformed JSON that JObject.Parse somehow accepted with a null data node.","commonSituations":"The tp.json file is corrupted, truncated, or from an incompatible version. A manual edit removed or renamed the 'data' field. The file was replaced with a different JSON structure. MapLazyAssets.Get() is called for the first time at startup, so this becomes a launch-time crash.","solutions":["Restore GameTask/AutoTrackPath/Assets/tp.json from the repository — verify it has a 'data' array key.","Validate the JSON with a linter to confirm the top-level structure is { \"data\": [ ... ] }.","Check that the file was not truncated during git operations (verify file size)."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"var json = File.ReadAllText(path);\nvar parsed = Newtonsoft.Json.Linq.JObject.Parse(json);\nif (parsed[\"data\"] == null || parsed[\"data\"]!.Type != Newtonsoft.Json.Linq.JTokenType.Array)\n{\n    // tp.json missing 'data' array — abort\n}","typeGuard":"static bool IsValidTpJson(string json)\n{\n    var token = Newtonsoft.Json.Linq.JObject.Parse(json)[\"data\"];\n    return token != null && token.Type == Newtonsoft.Json.Linq.JTokenType.Array;\n}","tryCatchPattern":"try { MapLazyAssets.Get(); }\ncatch (Exception ex) when (ex.Message.Contains(\"tp.json\")) { /* restore tp.json from repo */ }","preventionTips":["Include tp.json integrity check at startup.","Version-control tp.json and verify it is not truncated after checkout."],"tags":["json","map","teleport-data","corrupt-data"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}