babalae/better-genshin-impact · error · InvalidOperationException
意外的 token:{tokens[pos].Value}
Error message
意外的 token:{tokens[pos].Value} What it means
Thrown by ConditionEvaluator.ParsePrimary as a catch-all when the token at the current parse position is none of: LParen, Identifier, Number, or Bool. This means the grammar encountered a token where a primary expression (value or sub-expression) was expected but got an operator or comma instead. When called via Evaluate(), this is caught internally and Evaluate returns false.
Source
Thrown at BetterGenshinImpact/GameTask/AutoFight/Script/ConditionEvaluator.cs:381
pos++;
return new FuncCallNode(name, args);
}
return new FuncCallNode(name, []);
}
if (tokens[pos].Type == TokenType.Number)
{
var val = double.Parse(tokens[pos].Value, CultureInfo.InvariantCulture); pos++;
return new NumberNode(val);
}
if (tokens[pos].Type == TokenType.Bool)
{
var val = tokens[pos].Value == "true"; pos++;
return new BoolNode(val);
}
throw new InvalidOperationException($"意外的 token:{tokens[pos].Value}");
}
// ========== AST 求值(统一返回 object: double 或 bool) ==========
/// <summary>求值 AST 节点</summary>
private object Eval(AstNode node, int currentIndex)
{
return node switch
{
BoolNode b => b.Value,
NumberNode n => n.Value,
UnaryOpNode u => EvalUnary(u, currentIndex),
BinaryOpNode b => EvalBinary(b, currentIndex),
FuncCallNode f => EvalFunc(f.Name, f.Args, currentIndex),
_ => false
};
}
View on GitHub (pinned to a7cb36712d)
Solutions
- Inspect the token value in the error message to identify what was unexpected.
- Ensure each operand position has a valid primary expression (identifier, number, bool, function call, or parenthesized group).
- Remove double operators or misplaced commas.
- Test the expression in isolation with logging enabled to trace the parse.
Example fix
// before (dangling operator) "condition": "&& q-ready()" // after "condition": "q-ready()"
Defensive patterns
Strategy: try-catch
Try / catch
// Evaluate catches this internally (line 147-151) and returns false.
// To detect when a condition silently fails, wrap Evaluate with logging:
bool result;
try
{
result = evaluator.Evaluate(expr, idx, name, action);
}
catch
{
result = false; // Evaluate itself shouldn't throw, but be safe
}
Logger.LogDebug("条件 {Expr} => {Result}", expr, result); Prevention
- The Evaluate method handles this gracefully by returning false — no crash occurs.
- When a condition always evaluates false unexpectedly, review the expression for misplaced operators.
- Avoid starting expressions with operators (&&, ||) or placing operators in argument positions.
- Ensure function arguments are non-empty expressions between commas.
When it happens
Trigger: A malformed condition expression where an operator appears where a value is expected. For example: `&& q-ready()` (starts with operator), `q-ready(,)` (empty argument position), or `since()` followed immediately by a comma with no value. Also triggered by consecutive operators like `q-ready() && || low-hp()`.
Common situations: User writes a condition with a misplaced operator, empty argument, or dangling comma in a function call. Often from partial editing or incorrect copy-paste of expression fragments.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/83169962f6882e1b.
Report an issue: GitHub.