{"record":{"id":"d73156f4a1fe5780","repo":"HKUDS/Vibe-Trading","slug":"name-must-be-numeric","errorCode":null,"errorMessage":"{name} must be numeric","messagePattern":"(.+?) must be numeric","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/options_payoff_tool.py","lineNumber":265,"sourceCode":"            raise ValueError(f\"legs[{index}].qty must be a non-zero integer\")\n        qty = int(qty_number)\n        raw_premium = item.get(\"premium\")\n        try:\n            premium = None if raw_premium is None else float(raw_premium)\n        except (TypeError, ValueError, OverflowError) as exc:\n            raise ValueError(f\"legs[{index}].premium must be numeric or null\") from exc\n        legs.append(OptionLeg(option_type, strike, qty, premium))\n    return legs\n\n\ndef _required_float(kwargs: dict[str, Any], name: str) -> float:\n    \"\"\"Read a required finite float.\"\"\"\n    if name not in kwargs or kwargs[name] is None or kwargs[name] == \"\":\n        raise ValueError(f\"{name} is required\")\n    try:\n        value = float(kwargs[name])\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be numeric\") from exc\n    if not math.isfinite(value):\n        raise ValueError(f\"{name} must be finite\")\n    return value\n\n\ndef _optional_float(kwargs: dict[str, Any], name: str, default: float) -> float:\n    \"\"\"Read an optional finite float, treating null and empty text as omitted.\"\"\"\n    raw = kwargs.get(name)\n    if raw is None or raw == \"\":\n        return default\n    try:\n        value = float(raw)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be numeric\") from exc\n    if not math.isfinite(value):\n        raise ValueError(f\"{name} must be finite\")\n    return value\n","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/options_payoff_tool.py#L247-L283","documentation":"Thrown by _required_float when a required parameter is present but float() conversion fails — the value is a non-numeric string, a list/dict, or an unparseable type. Distinct from the 'is required' error: the key exists, its value just isn't a number.","triggerScenarios":"entry_spot=\"100 USD\", entry_spot=[100], entry_iv={\"value\":0.2}, or any object whose __float__ raises.","commonSituations":"Unparsed strings from chat/UI input; structured wrappers around scalars; locale-formatted numbers ('1.000,5').","solutions":["Convert to a plain float before the call","Strip non-numeric characters and re-validate: float(re.sub(r'[^0-9.\\-eE]', '', str(raw)))","Use strict numeric input types in the calling form/schema"],"exampleFix":"// before\nexecute({\"legs\": legs, \"entry_spot\": \"$105.20\"})\n// after\nexecute({\"legs\": legs, \"entry_spot\": 105.20})","handlingStrategy":"validation","validationCode":"try:\n    kwargs[\"entry_spot\"] = float(kwargs[\"entry_spot\"])\nexcept (TypeError, ValueError, OverflowError):\n    raise ValueError(\"entry_spot must be numeric\")","typeGuard":"def coercible_to_float(v) -> bool:\n    try: float(v); return True\n    except (TypeError, ValueError, OverflowError): return False","tryCatchPattern":"try:\n    execute(kwargs)\nexcept ValueError as e:\n    if \"must be numeric\" in str(e):\n        kwargs[name] = parse_number_from_text(kwargs[name])","preventionTips":["Coerce numerics at the boundary of your app","Use number-typed form fields","Locale-normalize decimal strings before conversion"],"tags":["validation","type-coercion","options"],"backgroundTag":"numeric-field-invalid","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}