HKUDS/Vibe-Trading · error · ValuationError

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

Error message

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

What it means

_require_finite coerces every opening figure and driver to float before projecting; if float(value) raises TypeError/ValueError (string like 'n/a', None, a list) it raises ValuationError naming the model and field. This stops non-numeric inputs from propagating into the solver and surfacing later as a confusing convergence failure.

Source

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

    """Check a value is a finite number, refusing NaN and infinity.

    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:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Find the field named in the message and convert it to a real number (float/int).
  2. Clean the source data: fill/replace empty or string values with numeric ones before building the dicts.
  3. Add a pass over opening/drivers with a numeric type check before calling project_three_statement.

Example fix

# before
opening = {"cash": None, ...}
project_three_statement(opening, drivers)
# after
opening = {"cash": 0.0, ...}  # or float(df.iloc[0]['cash']) after cleaning
project_three_statement(opening, drivers)
Defensive patterns

Strategy: validation

Validate before calling

for k, v in {**opening, **{f: x for f, xs in drivers.items() for x in [xs]}}.items():
    float(v)  # raises early with your own context

Type guard

def all_numeric(mapping) -> bool:
    try:
        [float(v) for v in mapping.values()]
        return True
    except (TypeError, ValueError):
        return False

Try / catch

except ValuationError as e:
    if 'must be a number' in str(e): clean_inputs_and_report(e)

Prevention

When it happens

Trigger: Calling project_three_statement with an opening dict or drivers mapping containing None, a non-numeric string, or a nested sequence where a scalar is expected — e.g. opening['cash'] = None from a pandas extraction.

Common situations: Loading drivers from YAML/CSV where empty cells become None or ''; JSON configs with stringly-typed numbers; dict keys from pandas rows returning objects.

Related errors


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