HKUDS/Vibe-Trading · error · ValuationError

{model}: eps_basis must be one of {EPS_BASES}, got {eps_basi

Error message

{model}: eps_basis must be one of {EPS_BASES}, got {eps_basis!r}

What it means

EPS basis must be one of the two recognised values in EPS_BASES (basic or diluted); _require_eps_basis runs at dataclass construction so a typo'd or foreign value fails immediately rather than silently skewing the P/E distribution.

Source

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

        cash_and_equivalents=float(cash_and_equivalents),
        minority_interest=minority_interest,
        preferred_stock=preferred_stock,
        investments_in_associates=investments_in_associates,
        omitted_components=omitted,
    )


def _require_name(name: str, model: str) -> str:
    """Reject a blank company name -- every report keys off it."""
    if not isinstance(name, str) or not name.strip():
        raise ValuationError(f"{model}: name is required and cannot be blank, got {name!r}")
    return name


def _require_eps_basis(eps_basis: str, model: str) -> str:
    """Reject an EPS basis that is not one of the two this module recognises."""
    if eps_basis not in EPS_BASES:
        raise ValuationError(
            f"{model}: eps_basis must be one of {EPS_BASES}, got {eps_basis!r}"
        )
    return eps_basis


@dataclass(frozen=True)
class PeerCompany:
    """One comparable company's raw inputs for the EV bridge and multiple matrix.

    Attributes:
        name: Identifier (ticker or short name), used in every report and
            exclusion message for this peer.
        market_cap: Equity market value.
        total_debt: Interest-bearing debt.
        cash_and_equivalents: Cash and short-term investments.
        ebitda: Fiscal-period figures for EBITDA.
        ebit: Fiscal-period figures for EBIT.
        revenue: Fiscal-period figures for revenue/sales.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Import EPS_BASES from the module and select from it instead of hardcoding strings.
  2. Normalize incoming basis strings (strip/lower) and map to the canonical values.
  3. Add a startup assertion listing valid choices for configuration-driven basis values.

Example fix

# before
peer = CompPeer(name='ACME', eps_basis='Diluted', ...)

# after
from quantlib.valuation.comps import EPS_BASES
assert eps_basis in EPS_BASES, f'{eps_basis=} not in {EPS_BASES}'
peer = CompPeer(name='ACME', eps_basis=eps_basis, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

from quantlib.valuation.comps import EPS_BASES
if eps_basis not in EPS_BASES:
    raise ValueError(f'eps_basis must be one of {EPS_BASES}')

Type guard

def valid_eps_basis(b):
    from quantlib.valuation.comps import EPS_BASES
    return b in EPS_BASES

Try / catch

except ValuationError as e:
    if 'eps_basis' in str(e):
        eps_basis = 'diluted'  # documented default choice

Prevention

When it happens

Trigger: Constructing a peer/target with eps_basis='Diluted' (wrong case), 'adj', 'gaap', or any string not exactly in EPS_BASES.

Common situations: Case mismatches from user config or CSV headers; new basis vocabulary added by a data vendor; hand-written literals drifting from the enum.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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