{"record":{"id":"f6ba6b69bf861c15","repo":"babalae/better-genshin-impact","slug":"json-action-name","errorCode":null,"errorMessage":"JSON 战斗策略中动作名称无法作为条件标识符解析：{action.Name}","messagePattern":"JSON 战斗策略中动作名称无法作为条件标识符解析：(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/AutoFight/Script/JsonCombatStrategyParser.cs","lineNumber":95,"sourceCode":"\n        return strategy;\n    }\n\n    /// <summary>\n    /// 校验动作名称合法性。\n    /// 动作名必须能作为条件表达式中的单个标识符解析（复用 <see cref=\"ConditionEvaluator.IsValidActionName\"/>：\n    /// 不能是布尔字面量 true/false、纯数字，不能含空白、逗号、运算符等，也不能与内置条件函数同名）。\n    /// 允许不同动作使用相同 index（since/count 等按 index 查询时取最近一次执行的事件记录）。\n    /// </summary>\n    private static void ValidateActions(List<JsonAction> actions)\n    {\n        var actionNames = actions.Where(a => !string.IsNullOrEmpty(a.Name)).Select(a => a.Name).ToList();\n        foreach (var action in actions)\n        {\n            if (!string.IsNullOrEmpty(action.Name) && !ConditionEvaluator.IsValidActionName(action.Name, actionNames))\n            {\n                Logger.LogError(\"JSON 战斗策略中动作名称无法作为条件标识符解析（不能是布尔字面量、纯数字，不能含空白、逗号、运算符等，也不能与内置条件函数同名）：{Name}\", action.Name);\n                throw new InvalidOperationException($\"JSON 战斗策略中动作名称无法作为条件标识符解析：{action.Name}\");\n            }\n        }\n    }\n}\n","sourceCodeStart":77,"sourceCodeEnd":100,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/AutoFight/Script/JsonCombatStrategyParser.cs#L77-L100","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rename the action to use only letters, digits, and hyphens (no spaces, commas, or operators).","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.","Do not use 'true', 'false', or pure numeric names.","Use hyphens for multi-word names (e.g. 'burst-phase' not 'burst phase')."],"exampleFix":"// before\n{ \"Name\": \"burst phase\", \"Index\": 2 }\n\n// after\n{ \"Name\": \"burst-phase\", \"Index\": 2 }","handlingStrategy":"validation","validationCode":"// Validate action names before parsing the strategy\nstatic readonly HashSet<string> ReservedNames = ConditionEvaluator.FunctionNames;\n\nstatic bool IsValidActionName(string name)\n{\n    if (string.IsNullOrEmpty(name)) return true; // empty names skip validation\n    if (bool.TryParse(name, out _)) return false;\n    if (ReservedNames.Contains(name)) return false;\n    if (double.TryParse(name, out _)) return false;\n    if (name.Any(c => char.IsWhiteSpace(c) || c == ',' || IsOperatorChar(c))) return false;\n    return true;\n}\n\nstatic bool IsOperatorChar(char c) => \"!&|+-*/<>=()\".Contains(c);","typeGuard":null,"tryCatchPattern":"try\n{\n    var strategy = JsonCombatStrategyParser.Parse(json);\n}\ncatch (InvalidOperationException e) when (e.Message.Contains(\"无法作为条件标识符解析\"))\n{\n    Logger.LogError(\"动作名称不合法: {Msg}\", e.Message);\n    // Fix the action name to use only letters, digits, and hyphens\n}","preventionTips":["Use only alphanumeric characters and hyphens for action names (e.g. 'burst-phase', 'opening').","Avoid reserved function names: q-ready, e-ready, since, count, min, max, etc.","Do not use spaces, commas, or operator characters in action names.","Do not use 'true', 'false', or pure numbers as action names."],"tags":["json-strategy","validation","action-name","identifier","condition-evaluator"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}