HKUDS/Vibe-Trading · error · ValuationError

{model}: {name} must be a finite number, got {numeric!r}

Error message

{model}: {name} must be a finite number, got {numeric!r}

What it means

After successful float coercion, _require_finite rejects NaN and +/-inf values with ValuationError. This guards the three-statement solver: a single non-finite opening balance or driver would poison every downstream period and end in a ConvergenceError or garbage output.

Source

Thrown at agent/src/quantlib/valuation/threestatement.py:471

    Args:
        value: The candidate value.
        name: Field name for the error message.
        model: Model name for the error message.

    Returns:
        ``value`` as a float.

    Raises:
        ValuationError: If the value is not a finite number. A non-finite
            driver or opening figure would otherwise flow into the projection
            and surface as a misleading "did not converge" error.
    """
    try:
        numeric = float(value)
    except (TypeError, ValueError) as exc:
        raise ValuationError(f"{model}: {name} must be a number, got {value!r}") from exc
    if not math.isfinite(numeric):
        raise ValuationError(
            f"{model}: {name} must be a finite number, got {numeric!r}"
        )
    return numeric


def _resolve_period_count(drivers: Mapping[str, Sequence[float]]) -> int:
    """Validate every driver sequence shares one non-zero length and return it.

    Args:
        drivers: The driver mapping already checked by
            :func:`~src.quantlib.valuation.contracts.require_inputs`.

    Returns:
        The number of periods to project.

    Raises:
        ValuationError: If the driver sequences disagree in length, or all are
            empty.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Trace the field named in the message to its source and fix the NaN/inf-producing step (e.g. zero-base division).
  2. Impute or drop the bad observation before building the drivers dict.
  3. Pre-screen with math.isfinite over all scalars in opening/drivers.

Example fix

# before
opening = {"cash": float('nan'), ...}
# after
opening = {"cash": 120.0, ...}  # cleaned/imputed value
Defensive patterns

Strategy: validation

Validate before calling

import math
assert all(math.isfinite(float(v)) for v in opening.values())
assert all(math.isfinite(x) for xs in drivers.values() for x in xs)

Type guard

def is_finite_scalar(x) -> bool:
    import math
    return isinstance(x, (int, float)) and math.isfinite(x)

Try / catch

except ValuationError as e:
    if 'finite number' in str(e): scrub_data(e)

Prevention

When it happens

Trigger: Calling project_three_statement with an opening value or driver entry that is float('nan'), math.inf, or numpy.inf — often from a division by zero or a pandas operation that produced NaN upstream.

Common situations: Pipeline data with missing observations forward-filled as NaN; growth rates computed as inf from 0-base revenue; Excel imports of #DIV/0! cells.

Related errors


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