HKUDS/Vibe-Trading · error · ValueError

{name} must be a finite number, got {value!r}

Error message

{name} must be a finite number, got {value!r}

What it means

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.

Source

Thrown at agent/src/tools/strategy_discovery_tool.py:92

        raise ValueError(f"{name} must be an integer, got {value!r}")
    try:
        return int(value)
    except (TypeError, ValueError, OverflowError) as exc:
        raise ValueError(f"{name} must be an integer, got {value!r}") from exc


def _coerce_opt_float(value: Any, name: str) -> float | None:
    """Coerce an optional numeric parameter; reject NaN/inf and bad types."""
    if value is None:
        return None
    if isinstance(value, bool):
        raise ValueError(f"{name} must be a number, got {value!r}")
    try:
        result = float(value)
    except (TypeError, ValueError, OverflowError) as exc:
        raise ValueError(f"{name} must be a number, got {value!r}") from exc
    if result != result or result in (float("inf"), float("-inf")):
        raise ValueError(f"{name} must be a finite number, got {value!r}")
    return result


def _coerce_opt_str(value: Any, name: str) -> str | None:
    """Coerce an optional string parameter; blank/None become ``None``."""
    if value is None:
        return None
    if not isinstance(value, str):
        raise ValueError(f"{name} must be a string, got {value!r}")
    if len(value) > _MAX_STRING_PARAM_CHARS:
        raise ValueError(
            f"{name} is too long ({len(value)} chars; "
            f"max {_MAX_STRING_PARAM_CHARS})"
        )
    text = value.strip()
    return text or None

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Sanitize NaN/inf to None (omit the filter) or a finite value before calling the tool
  2. Use math.isfinite() on computed thresholds before passing them
  3. Fix the upstream computation (e.g. guard divide-by-zero) that produced NaN/inf

Example fix

# before
value = df['sharpe'].min()  # may be nan
tool.execute(min_sharpe=value)
# after
import math
value = df['sharpe'].min()
tool.execute(min_sharpe=value if math.isfinite(value) else None)
Defensive patterns

Strategy: validation

Validate before calling

import math
value = None if value is None or not math.isfinite(float(value)) else float(value)
tool.execute(**{name: value})

Type guard

def is_finite_number(v) -> bool:
    return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v)

Prevention

When it happens

Trigger: 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")).

Common situations: 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.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/2f791300e848301e. Report an issue: GitHub.