HKUDS/Vibe-Trading · error · ValuationError

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

Error message

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

What it means

Optional EV-bridge components (minority_interest, preferred_stock, investments_in_associates) may be None (and are then reported as omitted), but if supplied they must be finite numbers. Supplying NaN/inf for one of them fails here so the bridge total cannot be corrupted.

Source

Thrown at agent/src/quantlib/valuation/comps.py:405

    if not math.isfinite(total_debt):
        raise ValuationError(
            f"comps: total_debt must be a finite number, got {total_debt!r}"
        )
    if not math.isfinite(cash_and_equivalents):
        raise ValuationError(
            f"comps: cash_and_equivalents must be a finite number, got {cash_and_equivalents!r}"
        )
    total = total_debt - cash_and_equivalents
    for name, value in (
        ("minority_interest", minority_interest),
        ("preferred_stock", preferred_stock),
        ("investments_in_associates", investments_in_associates),
    ):
        if value is None:
            omitted.append(name)
            continue
        if not math.isfinite(value):
            raise ValuationError(
                f"comps: {name} must be a finite number, got {value!r}"
            )
        sign = -1.0 if name == "investments_in_associates" else 1.0
        total += sign * value
    return total, tuple(omitted)


def enterprise_value(
    *,
    market_cap: float,
    total_debt: float,
    cash_and_equivalents: float,
    minority_interest: float | None = None,
    preferred_stock: float | None = None,
    investments_in_associates: float | None = None,
) -> EVBridgeResult:
    """Bridge a known equity market value to enterprise value.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Map missing optional components to None rather than NaN before calling the bridge.
  2. If you have a sourced value, ensure it is a plain finite float.
  3. Sanitize: {k: (v if v is not None and math.isfinite(v) else None) for k, v in components.items()}.

Example fix

# before
minority_interest = row['minority_interest']  # NaN

# after
minority_interest = row['minority_interest'] if row['minority_interest'] is not None and math.isfinite(row['minority_interest']) else None
Defensive patterns

Strategy: type-guard

Validate before calling

components = {k: (v if v is not None and math.isfinite(v) else None)
               for k, v in raw_components.items()}

Type guard

def finite_or_none(v):
    return None if v is None else (float(v) if math.isfinite(v) else None)

Try / catch

except ValuationError as e:
    if 'must be a finite number' in str(e):
        # fall back to omitting the component
        ev = enterprise_value(market_cap, total_debt, cash, minority_interest=None)

Prevention

When it happens

Trigger: Passing minority_interest=float('nan') (etc.) to enterprise_value or equity_value_from_enterprise_value instead of leaving it None or giving a finite value.

Common situations: Uniformly filling optional fields from a dict of extracted financials where some values are NaN, instead of mapping NaN -> None.

Related errors


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