{"record":{"id":"effa8584b5c13f5f","repo":"HKUDS/Vibe-Trading","slug":"malformed-expression-exc","errorCode":null,"errorMessage":"malformed expression: {exc}","messagePattern":"malformed expression: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/financial_rigor_tool.py","lineNumber":135,"sourceCode":"    The expression is parsed and evaluated recursively with Decimal arithmetic,\n    so ``0.1 + 0.2`` is exactly ``0.3`` — no IEEE-754 drift, and no ``eval``.\n    Only numbers and the operators ``+ - * /`` (with optional unary sign) are\n    permitted; any other AST node raises ``ValueError``.\n\n    Args:\n        expr: Arithmetic expression string, e.g. ``\"510 * 9.11e9\"``.\n\n    Returns:\n        The exact Decimal result.\n\n    Raises:\n        ValueError: If the expression is malformed or contains a disallowed\n            element.\n    \"\"\"\n    try:\n        tree = ast.parse(expr, mode=\"eval\")\n    except SyntaxError as exc:\n        raise ValueError(f\"malformed expression: {exc}\") from exc\n    return _eval_arith_node(tree.body)\n\n\n# ---------------------------------------------------------------------------\n# Core verification routines (pure, return structured dicts, no I/O)\n# ---------------------------------------------------------------------------\n\ndef verify_market_cap(\n    price: Any, shares: Any, reported_cap: Any, currency: str = \"\",\n) -> dict[str, Any]:\n    \"\"\"Verify ``market cap = price × shares`` against a reported value.\n\n    Args:\n        price: Current share price.\n        shares: Total share count.\n        reported_cap: The market-cap figure being checked.\n        currency: Optional currency label for display only.\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/financial_rigor_tool.py#L117-L153","documentation":"_safe_arith parses the expression with ast.parse(mode='eval'); a SyntaxError is wrapped into this ValueError so callers get a uniform validation exception. It fires before any evaluation, purely on unparseable input such as unbalanced parentheses or empty/garbage strings.","triggerScenarios":"Calling exact_calc or _safe_arith with '', '2 +', '(1+2', or non-Python text like 'two plus two'.","commonSituations":"User-typed formulas, truncated LLM output, or copy-paste artifacts (smart quotes, thousand separators like '1,000')","solutions":["Sanitize the input (strip commas/currency symbols, normalize quotes) before calling","Validate the expression with ast.parse in the caller for a cleaner upstream error","Retry with a corrected expression when the tool reports a parse failure"],"exampleFix":"# before\nexact_calc(\"1,000 * 0.05\")\n# after\nexact_calc(\"1000 * 0.05\")","handlingStrategy":"validation","validationCode":"import ast\nexpr = user_input.replace(\",\", \"\").replace(\"$\", \"\")\ntry:\n    ast.parse(expr, mode=\"eval\")\nexcept SyntaxError as e:\n    raise ValueError(f\"bad formula at col {e.offset}: {e.msg}\") from e","typeGuard":null,"tryCatchPattern":"try:\n    value = _safe_arith(expr)\nexcept ValueError as e:\n    if str(e).startswith(\"malformed expression\"):\n        return None / re-ask user for a corrected formula\n    raise","preventionTips":["Normalize input: strip commas, currency symbols, smart quotes","ast.parse upstream for clearer error positions","Never pass empty strings; short-circuit to Decimal(0)"],"tags":["python","parsing","validation","expression-eval"],"backgroundTag":"syntax-error-in-expression","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}