babalae/better-genshin-impact · error · InvalidOperationException

无法识别的字符:'{c}'

Error message

无法识别的字符:'{c}'

What it means

Thrown by ConditionEvaluator.Tokenize when the lexer encounters a character that is not whitespace, a recognized operator (&&, ||, !, +, -, *, /, >, <, =), parenthesis, comma, digit, or letter. The tokenizer has no rule for the character and aborts. Note: when called via Evaluate(), this exception is caught internally (line 147-151) and Evaluate returns false instead of propagating. When called via IsValidActionName(), it is also caught and returns false.

Source

Thrown at BetterGenshinImpact/GameTask/AutoFight/Script/ConditionEvaluator.cs:224

                // 多段动作名(如 芙芙-e-开场)只需其完整名称已声明即可整体并入,中间段无需单独声明;
                // 没有任何已知前缀时 `-` 保持为独立减号运算符(如 t-5、since(1)-3)
                if (i < expr.Length && expr[i] == '-')
                {
                    var candidateEnd = i + 1;
                    while (candidateEnd < expr.Length && (char.IsLetterOrDigit(expr[candidateEnd]) || expr[candidateEnd] == '-'))
                        candidateEnd++;
                    while (candidateEnd > i && !knownIdentifiers.Contains(expr[start..candidateEnd]))
                        candidateEnd--;
                    if (candidateEnd > i) i = candidateEnd;
                }
                var word = expr[start..i];
                tokens.Add(word is "true" or "false"
                    ? new Token(TokenType.Bool, word)
                    : new Token(TokenType.Identifier, word));
                continue;
            }

            throw new InvalidOperationException($"无法识别的字符:'{c}'");
        }

        tokens.Add(new Token(TokenType.End, ""));
        return tokens;
    }

    // ========== 语法分析(递归下降) ==========

    private abstract class AstNode { }

    private class BoolNode(bool value) : AstNode { public bool Value { get; } = value; }

    private class NumberNode(double value) : AstNode { public double Value { get; } = value; }

    private class FuncCallNode(string name, List<AstNode> args) : AstNode
    {
        public string Name { get; } = name;
        public List<AstNode> Args { get; } = args;

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Inspect the condition expression for non-grammar characters (the exception message quotes the offending character).
  2. Replace unsupported syntax: use '(' ')' for grouping instead of '[' ']', use '&&' '||' instead of other boolean operators.
  3. Refer to supported operators: ||, &&, !, (), +, -, *, /, >, <, =, and function calls.
  4. Validate the expression with ConditionEvaluator.IsValidActionName or a dry-run Evaluate before committing.

Example fix

// before (unsupported square brackets)
"condition": "count[3] > 2"

// after (use function call syntax)
"condition": "count(3) > 2"
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate a condition expression for unsupported characters before use
static bool HasValidChars(string expr)
{
    var allowed = "()&&!+-*/<>=,. ";
    foreach (var c in expr)
    {
        if (char.IsLetterOrDigit(c) || allowed.Contains(c)) continue;
        return false;
    }
    return true;
}

if (!HasValidChars(conditionExpr))
    throw new ArgumentException($"条件表达式含不支持的字符: {conditionExpr}");

Try / catch

// Evaluate already catches InvalidOperationException internally and returns false.
// For direct Tokenize use (rare), wrap in try-catch:
try
{
    var tokens = Tokenize(expr, knownIdentifiers);
}
catch (InvalidOperationException e) when (e.Message.Contains("无法识别的字符"))
{
    Logger.LogWarning("条件表达式包含不支持的字符: {Msg}", e.Message);
    return false;
}

Prevention

When it happens

Trigger: A condition expression string contains an unsupported character such as '@', '#', '%', '^', '&', '~', '[', ']', '{', '}', or any non-ASCII symbol that is not a recognized CJK letter. For example: `q-ready() & low-hp@` or `count[3] > 2`.

Common situations: User writes a JSON strategy condition expression with a typo using square brackets, '@', or other symbols not in the supported grammar. Could also occur from copy-paste of programming syntax (array indexing, ternary operators) into the condition DSL.

Related errors


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