HKUDS/Vibe-Trading · error · ValueError
unsupported unary operator: {type(node.op).__name__}
Error message
unsupported unary operator: {type(node.op).__name__} What it means
Raised when a UnaryOp in the arithmetic AST uses an operator absent from _AST_UNARYOPS (typically only UAdd and USub). Operators like `not` (ast.Not) or `~` (ast.Invert) are rejected to keep the evaluator in the pure numeric Decimal domain. The message names the operator class for diagnostics.
Source
Thrown at agent/src/tools/financial_rigor_tool.py:109
The exact Decimal value of the node.
Raises:
ValueError: If the node is not a supported numeric/arithmetic form.
"""
if isinstance(node, ast.Constant):
# bool is a subclass of int — reject it explicitly.
if isinstance(node.value, bool) or not isinstance(node.value, (int, float)):
raise ValueError("only numeric constants are allowed")
return _exact(node.value)
if isinstance(node, ast.BinOp):
op_fn = _AST_BINOPS.get(type(node.op))
if op_fn is None:
raise ValueError(f"unsupported operator: {type(node.op).__name__}")
return op_fn(_eval_arith_node(node.left), _eval_arith_node(node.right))
if isinstance(node, ast.UnaryOp):
op_fn = _AST_UNARYOPS.get(type(node.op))
if op_fn is None:
raise ValueError(f"unsupported unary operator: {type(node.op).__name__}")
return op_fn(_eval_arith_node(node.operand))
raise ValueError(f"disallowed element in expression: {type(node).__name__}")
def _safe_arith(expr: str) -> Decimal:
"""Evaluate a numeric arithmetic expression in the exact-Decimal domain.
The expression is parsed and evaluated recursively with Decimal arithmetic,
so ``0.1 + 0.2`` is exactly ``0.3`` — no IEEE-754 drift, and no ``eval``.
Only numbers and the operators ``+ - * /`` (with optional unary sign) are
permitted; any other AST node raises ``ValueError``.
Args:
expr: Arithmetic expression string, e.g. ``"510 * 9.11e9"``.
Returns:
The exact Decimal result.
View on GitHub (pinned to 80ffdda44c)
Solutions
- Remove boolean/bitwise unary operators from the expression
- Pre-validate the expression string with a regex/AST check before submitting
- Extend _AST_UNARYOPS only if a Decimal-safe semantics exists for the operator
Example fix
// before
_safe_arith("~0")
// after
_safe_arith("-0") Defensive patterns
Strategy: validation
Validate before calling
import ast expr = "~5" tree = ast.parse(expr, mode="eval") assert all(type(n.op) in (ast.UAdd, ast.USub) for n in ast.walk(tree) if isinstance(n, ast.UnaryOp)), "disallowed unary op"
Type guard
def has_only_numeric_unary(expr: str) -> bool:
import ast
try:
tree = ast.parse(expr, mode="eval")
except SyntaxError:
return False
return all(type(n.op) in (ast.UAdd, ast.USub) for n in ast.walk(tree) if isinstance(n, ast.UnaryOp)) Try / catch
try:
value = _safe_arith(expr)
except ValueError as e:
if "unary operator" in str(e):
raise UserInputError(f"rewrite {expr!r} without boolean/bitwise unary ops")
raise Prevention
- Strip 'not ', '~', '!' from generated expressions
- Pre-parse expressions to enumerate operators before evaluation
When it happens
Trigger: Calling exact_calc/_safe_arith with expressions like 'not 1', '~5', or any unary operator other than +/-.
Common situations: Users pasting boolean logic or bitwise negation into a strictly numeric financial calculator; LLM-generated expressions mixing boolean and arithmetic syntax.
Related errors
- unsupported operator: {type(node.op).__name__}
- disallowed element in expression: {type(node).__name__}
- only numeric constants are allowed
- malformed expression: {exc}
- invalid alpha_id
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/823dfe6134552b2f.
Report an issue: GitHub.