{"record":{"id":"9ecb7ade597e9e6c","repo":"babalae/better-genshin-impact","slug":"name-9ecb7a","errorCode":null,"errorMessage":"未知条件函数：{name}","messagePattern":"未知条件函数：(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/AutoFight/Script/ConditionEvaluator.cs","lineNumber":456,"sourceCode":"        // 函数名大小写不敏感（min/MIN、MAX/max 均可）\n        name = name.ToLowerInvariant();\n        return name switch\n        {\n            \"last-exec\" => EvalLastExec(args, currentIndex),\n            \"q-ready\" => EvalQReady(args),\n            \"e-ready\" => EvalEReady(args),\n            \"e-cd\" => EvalECd(args),\n            \"low-hp\" => EvalLowHp(),\n            \"battle-time\" => EvalBattleTime(args),\n            \"in-party\" => EvalInParty(args),\n            \"onfield\" => EvalOnField(),\n            \"t\" => EvalT(),\n            \"since\" => EvalSince(args, currentIndex),\n            \"count\" => EvalCount(args, currentIndex),\n            \"min\" => EvalMinMax(args, currentIndex, isMax: false),\n            \"max\" => EvalMinMax(args, currentIndex, isMax: true),\n            \"last-check\" => EvalLastCheck(),\n            _ => throw new InvalidOperationException($\"未知条件函数：{name}\")\n        };\n    }\n\n    // ========== 类型转换 ==========\n\n    /// <summary>将对象转换为 bool</summary>\n    private static bool ToBool(object val)\n    {\n        return val switch\n        {\n            bool b => b,\n            double d => d > 0,\n            _ => false\n        };\n    }\n\n    /// <summary>将对象转换为 double</summary>\n    private static double ToNumber(object val)","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/AutoFight/Script/ConditionEvaluator.cs#L438-L474","documentation":"Thrown by ConditionEvaluator.EvalFunc when a function call's name does not match any of the built-in condition functions (last-exec, q-ready, e-ready, e-cd, low-hp, battle-time, in-party, onfield, t, since, count, min, max, last-check). The function name is lowercased before matching, so case differences are not the issue — the name itself is unrecognized. When called via Evaluate(), this is caught internally and Evaluate returns false.","triggerScenarios":"A condition expression calls a function whose name is not in the built-in function list and is not a declared action name used as a zero-arg function reference. For example: `hp-ready()` (not a real function), `energy(>5)`, or a typo like `q_reday()`.","commonSituations":"User misspells a built-in function name, invents a function that doesn't exist, or references an action name that wasn't declared in the strategy. The grammar allows bare identifiers to be treated as zero-arg function calls, so any unknown name reaches EvalFunc and fails here.","solutions":["Check the function name in the error message ({name}) against the supported list.","Fix typos in function names (e.g., 'q-ready' not 'q_reday', 'low-hp' not 'lowhp').","If referencing an action by name, ensure the action is declared in the strategy's Actions list.","Refer to the supported functions documented in the ConditionEvaluator class header."],"exampleFix":"// before (typo in function name)\n\"condition\": \"q_reday()\"\n\n// after\n\"condition\": \"q-ready()\"","handlingStrategy":"validation","validationCode":"// Validate function names against the known set before evaluation\nstatic readonly HashSet<string> KnownFunctions = ConditionEvaluator.FunctionNames;\n\nstatic bool UsesOnlyKnownFunctions(string expr, HashSet<string> actionNames)\n{\n    // Extract function-call names and check each\n    var tokens = expr.Split([' ', '(', ')', ',', '!', '&', '|', '+', '-', '*', '/', '<', '>', '='],\n                           StringSplitOptions.RemoveEmptyEntries);\n    foreach (var t in tokens)\n    {\n        if (!char.IsLetter(t[0])) continue;\n        if (t is \"true\" or \"false\") continue;\n        if (double.TryParse(t, out _)) continue;\n        if (!KnownFunctions.Contains(t) && !actionNames.Contains(t))\n            return false;\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"// Evaluate catches this internally and returns false.\n// The warning log includes the expression and the unknown function name.\n// Check logs for '条件表达式求值失败' with '未知条件函数' in the message.","preventionTips":["Use only documented function names: last-exec, q-ready, e-ready, e-cd, low-hp, battle-time, in-party, onfield, t, since, count, min, max, last-check.","Function names are case-insensitive (min/MIN both work) but spelling must be correct.","When referencing action names as zero-arg functions, ensure they are declared in the strategy.","Test conditions with a dry-run Evaluate and check the warning log for unknown function errors."],"tags":["condition-evaluator","expression","function-call","unknown-function"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}