babalae/better-genshin-impact · error · Exception
Failed to deserialize JSON.
Error message
Failed to deserialize JSON.
What it means
Thrown in BaseMapLayerByTemplateMatch.LoadLayers when JsonSerializer.Deserialize<List<BaseMapLayerByTemplateMatch>>(json) returns null. System.Text.Json returns null when the JSON payload is the literal 'null' token or an empty/malformed file deserializes to null for a reference type. An empty array '[]' deserializes to an empty list (not null), so this specifically indicates a null-bearing document.
Source
Thrown at BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayerByTemplateMatch.cs:59
var grayMapPath = Path.Combine(layerDir, grayMapFileName);
FineGrayMap = Bv.ImRead(grayMapPath, ImreadModes.Grayscale)?? throw new Exception($"灰度分层地图 {LayerId} 读取失败");
speedTimer.Record("粗匹配用灰度图");
speedTimer.DebugPrint();
}
public static List<BaseMapLayerByTemplateMatch> LoadLayers(SceneBaseMapByTemplateMatch sceneBaseMap)
{
var layers = new List<BaseMapLayerByTemplateMatch>();
var layerDir = Path.Combine(Global.Absolute(@"Assets\Map\"), sceneBaseMap.Type.ToString());
if (!Directory.Exists(layerDir))
{
return layers;
}
var jsonFiles = Directory.GetFiles(layerDir, "*.json", SearchOption.AllDirectories);
foreach (var jsonFile in jsonFiles)
{
var json = File.ReadAllText(jsonFile);
var tempLayers = JsonSerializer.Deserialize<List<BaseMapLayerByTemplateMatch>>(json) ?? throw new Exception("Failed to deserialize JSON.");
layers.AddRange(tempLayers);
}
foreach (var layer in layers)
{
layer.LoadLayer(layerDir);
}
return layers;
}
public (Point2f, double) RoughMatch(Mat[] maskedMiniMaps, Mat maskF)
{
var (pos, val) = CoarseColorMatcher.Match(maskedMiniMaps, maskF);
return (MapToWorld(pos, RoughZoom, RoughSize), val);
}
public (Point2f, double) RoughMatch(Mat[] maskedMiniMaps, Mat maskF, Point2f preLoc, int[]? channels = null)
{
var roughPos = WorldToMap(preLoc, RoughZoom);View on GitHub (pinned to a7cb36712d)
Solutions
- Open each *.json under Assets\Map\<Type> and find the one that is 'null' or empty; replace it with a valid layer array.
- Restrict the JSON search to files matching the layer naming scheme instead of all *.json.
- Treat null as an empty list rather than fatal: use 'tempLayers ?? new()' or skip the file with a warning.
Example fix
// before
var tempLayers = JsonSerializer.Deserialize<List<BaseMapLayerByTemplateMatch>>(json) ?? throw new Exception("Failed to deserialize JSON.");
// after — tolerate a null document and report which file is bad
var tempLayers = JsonSerializer.Deserialize<List<BaseMapLayerByTemplateMatch>>(json);
if (tempLayers == null || tempLayers.Count == 0)
{
Logger.LogWarning("地图层 JSON 文件内容为空,已跳过: {File}", jsonFile);
continue;
}
layers.AddRange(tempLayers); Defensive patterns
Strategy: validation
Validate before calling
var json = File.ReadAllText(jsonFile);
if (string.IsNullOrWhiteSpace(json) || json.Trim() == "null")
{
Logger.LogWarning("跳过空的地图层 JSON: {File}", jsonFile);
continue;
} Try / catch
try { var tempLayers = JsonSerializer.Deserialize<List<BaseMapLayerByTemplateMatch>>(json); }
catch (JsonException ex) { Logger.LogError(ex, "JSON 反序列化失败: {File}", jsonFile); throw; } Prevention
- Keep map directories free of unrelated *.json files.
- Validate JSON is a non-null array before deserializing.
- Name layer JSON files consistently and filter by pattern.
When it happens
Trigger: LoadLayers reads every *.json under layerDir (recursive) and deserializes each. If any JSON file contains just 'null' (e.g. a placeholder, a mis-saved file, or an editor that wrote null), the result is null and this throws.
Common situations: A hand-edited or auto-generated JSON file contains the literal null; a file was truncated to empty and a default/null was written; an unrelated .json (e.g. a config) was placed in the map directory and happens to deserialize to null.
Related errors
- 分层地图数据文件夹中中存在无法解析的文件名: {fileName}
- 地图数据加载失败,文件: {kpFilePath}
- 地图数据加载失败,文件: {matFilePath}
- 彩色分层地图 {LayerId} 读取失败
- 灰度分层地图 {LayerId} 读取失败
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/dd09ac119849a557.
Report an issue: GitHub.