{"record":{"id":"2f791300e848301e","repo":"HKUDS/Vibe-Trading","slug":"name-must-be-a-finite-number-got-value-r-2f7913","errorCode":null,"errorMessage":"{name} must be a finite number, got {value!r}","messagePattern":"(.+?) must be a finite number, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/strategy_discovery_tool.py","lineNumber":92,"sourceCode":"        raise ValueError(f\"{name} must be an integer, got {value!r}\")\n    try:\n        return int(value)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be an integer, got {value!r}\") from exc\n\n\ndef _coerce_opt_float(value: Any, name: str) -> float | None:\n    \"\"\"Coerce an optional numeric parameter; reject NaN/inf and bad types.\"\"\"\n    if value is None:\n        return None\n    if isinstance(value, bool):\n        raise ValueError(f\"{name} must be a number, got {value!r}\")\n    try:\n        result = float(value)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be a number, got {value!r}\") from exc\n    if result != result or result in (float(\"inf\"), float(\"-inf\")):\n        raise ValueError(f\"{name} must be a finite number, got {value!r}\")\n    return result\n\n\ndef _coerce_opt_str(value: Any, name: str) -> str | None:\n    \"\"\"Coerce an optional string parameter; blank/None become ``None``.\"\"\"\n    if value is None:\n        return None\n    if not isinstance(value, str):\n        raise ValueError(f\"{name} must be a string, got {value!r}\")\n    if len(value) > _MAX_STRING_PARAM_CHARS:\n        raise ValueError(\n            f\"{name} is too long ({len(value)} chars; \"\n            f\"max {_MAX_STRING_PARAM_CHARS})\"\n        )\n    text = value.strip()\n    return text or None\n\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/strategy_discovery_tool.py#L74-L110","documentation":"strategy_discovery_tool._coerce_opt_float requires finite numbers: after a successful float() conversion it checks result != result (NaN) and membership in (inf, -inf), raising ValueError for non-finite values. This keeps NaN/Infinity out of downstream strategy-filter arithmetic and serialization.","triggerScenarios":"Passing float('nan'), float('inf'), or the strings \"nan\"/\"infinity\"/\"-inf\" (float() parses these successfully) for a numeric parameter; e.g. execute(min_sharpe=float(\"nan\")).","commonSituations":"Pandas/numpy computations producing NaN/inf that are forwarded unchecked; JSON parsers accepting Infinity/NaN (non-strict mode); division-by-zero results upstream feeding thresholds.","solutions":["Sanitize NaN/inf to None (omit the filter) or a finite value before calling the tool","Use math.isfinite() on computed thresholds before passing them","Fix the upstream computation (e.g. guard divide-by-zero) that produced NaN/inf"],"exampleFix":"# before\nvalue = df['sharpe'].min()  # may be nan\ntool.execute(min_sharpe=value)\n# after\nimport math\nvalue = df['sharpe'].min()\ntool.execute(min_sharpe=value if math.isfinite(value) else None)","handlingStrategy":"validation","validationCode":"import math\nvalue = None if value is None or not math.isfinite(float(value)) else float(value)\ntool.execute(**{name: value})","typeGuard":"def is_finite_number(v) -> bool:\n    return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v)","tryCatchPattern":null,"preventionTips":["Run math.isfinite over pandas/numpy results before passing them as thresholds","Convert NaN/inf to None (omit the filter) at the boundary"],"tags":["strategy-discovery","nan","infinity","finite-validation"],"backgroundTag":"non-finite-number-rejected","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}