HKUDS/Vibe-Trading · error · ValueError
only numeric constants are allowed
Error message
only numeric constants are allowed
What it means
The tool evaluates user-supplied arithmetic expressions by walking the AST and only allows numeric int/float constants (bools explicitly rejected since bool subclasses int) plus a whitelist of binary operators. Any non-numeric constant — strings, None, True/False — raises this ValueError, preventing code injection and type confusion in exact arithmetic.
Source
Thrown at agent/src/tools/financial_rigor_tool.py:99
return f"{value:,.2f}"
def _eval_arith_node(node: ast.AST) -> Decimal:
"""Recursively evaluate an arithmetic AST node in the Decimal domain.
Args:
node: An AST node from a parsed expression.
Returns:
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,View on GitHub (pinned to 80ffdda44c)
Solutions
- Ensure the expression contains only bare numeric literals and whitelisted operators
- Remove quotes around numbers ('2' -> 2) and replace True/False with 1/0 if arithmetic is intended
- Pre-validate the expression string with a regex/ast scan allowing only Constant(int/float) and whitelisted BinOps before evaluation
Example fix
# before
_safe_arith("100 * '2'") # string constant -> ValueError
_safe_arith("price * 1.1") # names are not constants
# after
_safe_arith("100 * 2")
_safe_arith("110.00000000000001") Defensive patterns
Strategy: validation
Validate before calling
import ast, re
NUM_EXPR = re.compile(r"^[\d\s.()+\-*/%]+$$")
def looks_safe(expr: str) -> bool:
if not NUM_EXPR.match(expr):
return False
try:
tree = ast.parse(expr, mode="eval")
except SyntaxError:
return False
return all(
isinstance(n, (ast.Expression, ast.BinOp, ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod, ast.USub, ast.UAdd, ast.Load))
or (isinstance(n, ast.Constant) and isinstance(n.value, (int, float)) and not isinstance(n.value, bool))
for n in ast.walk(tree)
) Type guard
def is_numeric_literal(node: ast.AST) -> bool:
return (
isinstance(node, ast.Constant)
and not isinstance(node.value, bool)
and isinstance(node.value, (int, float))
) Try / catch
try:
value = _safe_arith(expr)
except ValueError as exc:
if "only numeric constants" in str(exc):
expr = re.sub(r"'([\d.]+)'", r"\1", expr) # unquote numeric strings
value = _safe_arith(expr)
else:
raise Prevention
- Reject expression strings containing quotes, letters, or True/False before evaluation
- Pre-validate with an AST walk that only numeric Constant nodes and whitelisted operators appear
- Never pass raw user/LLM text into arithmetic evaluators without sanitization
When it happens
Trigger: Passing an expression containing a string literal like 100 * '2', booleans like True + 1, None, or any non-AST-constant numeric form into _safe_arith; unsupported operators raise a sibling error instead.
Common situations: LLM-generated formulas quoting numbers as strings; formulas using boolean flags; users pasting full Python expressions (variables, function calls) that reach the constant check via unexpected node types.
Related errors
- unsupported operator: {type(node.op).__name__}
- unsupported unary operator: {type(node.op).__name__}
- invalid alpha_id
- alpha_id not found
- invalid period: {exc}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/7c40c8291f1fb238.
Report an issue: GitHub.