babalae/better-genshin-impact · error · InvalidOperationException

JSON 战斗策略缺少 Info 节点

Error message

JSON 战斗策略缺少 Info 节点

What it means

Thrown by JsonCombatStrategyParser.Parse when the deserialized strategy object is non-null but its Info property is null. The Info node is required — it contains strategy metadata (name, etc.). This means the JSON object exists but lacks the 'Info' key or it was explicitly set to null.

Solutions

  1. Add an 'Info' object with at least a 'Name' property to the JSON strategy.
  2. Use the documented JSON strategy schema/template as a starting point.
  3. Example: "Info": { "Name": "MyCombatStrategy" }.

Example fix

// before (missing Info)
{
  "Actions": [ { "Name": "a1", "Index": 1 } ]
}

// after
{
  "Info": { "Name": "MyStrategy" },
  "Actions": [ { "Name": "a1", "Index": 1 } ]
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check for the Info node using a lightweight parse
using System.Text.Json;

var doc = System.Text.Json.JsonDocument.Parse(json);
if (!doc.RootElement.TryGetProperty("Info", out _) || doc.RootElement.GetProperty("Info").ValueKind == JsonValueKind.Null)
{
    throw new ArgumentException("策略缺少 Info 节点");
}

Try / catch

try
{
    var strategy = JsonCombatStrategyParser.Parse(json);
}
catch (InvalidOperationException e) when (e.Message.Contains("缺少 Info 节点"))
{
    Logger.LogError("策略缺少 Info 节点,请添加 Info 对象");
}

Prevention

When it happens

Trigger: The JSON file has an 'Actions' array but no 'Info' object, or 'Info' is present but set to null. For example: `{ "Actions": [...] }` without an Info key, or `{ "Info": null, "Actions": [...] }`.

Common situations: User creates a strategy file from a partial template that omitted the Info section, or deletes the Info block while editing. The Info node carries the human-readable strategy name used in logs.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/e52deb1f1a2fe171. Report an issue: GitHub.

Appendix: source

Thrown at BetterGenshinImpact/GameTask/AutoFight/Script/JsonCombatStrategyParser.cs:63

        {
            strategy = JsonConvert.DeserializeObject<JsonCombatStrategy>(json);
        }
        catch (JsonException ex)
        {
            Logger.LogError("JSON 战斗策略解析失败:{Msg}", ex.Message);
            throw new InvalidOperationException($"JSON 战斗策略格式错误:{ex.Message}", ex);
        }

        if (strategy == null)
        {
            Logger.LogError("JSON 战斗策略反序列化结果为空");
            throw new InvalidOperationException("JSON 战斗策略反序列化失败");
        }

        if (strategy.Info == null)
        {
            Logger.LogError("JSON 战斗策略缺少 Info 节点");
            throw new InvalidOperationException("JSON 战斗策略缺少 Info 节点");
        }

        if (strategy.Actions == null || strategy.Actions.Count == 0)
        {
            Logger.LogError("JSON 战斗策略缺少 Actions 节点或动作为空");
            throw new InvalidOperationException("JSON 战斗策略中未定义任何动作");
        }

        // 校验动作合法性(名称需能作为条件标识符解析;index 允许重复)
        ValidateActions(strategy.Actions);

        Logger.LogInformation("JSON 战斗策略加载完成:{Name},共 {Count} 个动作",
            strategy.Info.Name, strategy.Actions.Count);

        return strategy;
    }

    /// <summary>

View on GitHub (pinned to a7cb36712d)