babalae/better-genshin-impact · error · InvalidOperationException

JSON 战斗策略中动作名称无法作为条件标识符解析:{action.Name}

Error message

JSON 战斗策略中动作名称无法作为条件标识符解析:{action.Name}

What it means

Thrown by JsonCombatStrategyParser.ValidateActions when an action's Name fails ConditionEvaluator.IsValidActionName validation. Action names must be usable as single identifiers in condition expressions: they cannot be 'true'/'false', pure numbers, contain whitespace/commas/operators, or collide with built-in function names (q-ready, since, count, etc.).

Source

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

        return strategy;
    }

    /// <summary>
    /// 校验动作名称合法性。
    /// 动作名必须能作为条件表达式中的单个标识符解析(复用 <see cref="ConditionEvaluator.IsValidActionName"/>:
    /// 不能是布尔字面量 true/false、纯数字,不能含空白、逗号、运算符等,也不能与内置条件函数同名)。
    /// 允许不同动作使用相同 index(since/count 等按 index 查询时取最近一次执行的事件记录)。
    /// </summary>
    private static void ValidateActions(List<JsonAction> actions)
    {
        var actionNames = actions.Where(a => !string.IsNullOrEmpty(a.Name)).Select(a => a.Name).ToList();
        foreach (var action in actions)
        {
            if (!string.IsNullOrEmpty(action.Name) && !ConditionEvaluator.IsValidActionName(action.Name, actionNames))
            {
                Logger.LogError("JSON 战斗策略中动作名称无法作为条件标识符解析(不能是布尔字面量、纯数字,不能含空白、逗号、运算符等,也不能与内置条件函数同名):{Name}", action.Name);
                throw new InvalidOperationException($"JSON 战斗策略中动作名称无法作为条件标识符解析:{action.Name}");
            }
        }
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Rename the action to use only letters, digits, and hyphens (no spaces, commas, or operators).
  2. Avoid reserved function names: last-exec, q-ready, e-ready, e-cd, low-hp, battle-time, in-party, onfield, t, since, count, min, max, last-check.
  3. Do not use 'true', 'false', or pure numeric names.
  4. Use hyphens for multi-word names (e.g. 'burst-phase' not 'burst phase').

Example fix

// before
{ "Name": "burst phase", "Index": 2 }

// after
{ "Name": "burst-phase", "Index": 2 }
Defensive patterns

Strategy: validation

Validate before calling

// Validate action names before parsing the strategy
static readonly HashSet<string> ReservedNames = ConditionEvaluator.FunctionNames;

static bool IsValidActionName(string name)
{
    if (string.IsNullOrEmpty(name)) return true; // empty names skip validation
    if (bool.TryParse(name, out _)) return false;
    if (ReservedNames.Contains(name)) return false;
    if (double.TryParse(name, out _)) return false;
    if (name.Any(c => char.IsWhiteSpace(c) || c == ',' || IsOperatorChar(c))) return false;
    return true;
}

static bool IsOperatorChar(char c) => "!&|+-*/<>=()".Contains(c);

Try / catch

try
{
    var strategy = JsonCombatStrategyParser.Parse(json);
}
catch (InvalidOperationException e) when (e.Message.Contains("无法作为条件标识符解析"))
{
    Logger.LogError("动作名称不合法: {Msg}", e.Message);
    // Fix the action name to use only letters, digits, and hyphens
}

Prevention

When it happens

Trigger: A JSON strategy action has a name like 'true', '123', 'my action' (contains space), 'q-ready' (reserved function name), or 'my,name' (contains comma). The validator runs the name through the condition expression tokenizer and checks that it produces exactly one identifier token.

Common situations: User names an action with a space, number, reserved keyword, or special character, intending to reference it in conditions (e.g. `since(my action)`). The name must be a clean identifier for the expression engine to tokenize it correctly.

Related errors


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