HKUDS/Vibe-Trading · error · ValueError

TerminalValueResult.terminal_growth.value={self.terminal_gro

Error message

TerminalValueResult.terminal_growth.value={self.terminal_growth.value!r} is not below wacc_rate={self.wacc_rate!r}

What it means

TerminalValueResult.__post_init__ independently re-checks that terminal_growth.value < wacc_rate, guarding the Gordon-growth denominator. terminal_value() should have refused such inputs first; this is a second line of defense against inconsistent construction.

Source

Thrown at agent/src/quantlib/valuation/dcf.py:711

    perpetuity_terminal_value: float
    terminal_year_ebitda: float
    exit_multiple: Assumption
    exit_terminal_value: float
    implied_ev_ebitda_multiple: float
    implied_perpetuity_growth: float
    gdp_growth_ceiling: float
    growth_exceeds_gdp_ceiling: bool

    def __post_init__(self) -> None:
        """Re-check that the stored growth rate is still below WACC.

        Raises:
            ValueError: If ``terminal_growth.value >= wacc_rate``. This should
                already have been refused by :func:`terminal_value` before
                construction; this is a second, independent check.
        """
        if float(self.terminal_growth.value) >= self.wacc_rate:
            raise ValueError(
                f"TerminalValueResult.terminal_growth.value="
                f"{self.terminal_growth.value!r} is not below wacc_rate="
                f"{self.wacc_rate!r}"
            )


def terminal_value(
    *,
    final_year_fcff: float,
    terminal_year_ebitda: float,
    wacc_rate: float,
    terminal_growth: Assumption,
    exit_multiple: Assumption,
    gdp_growth_ceiling: float = DEFAULT_LONG_RUN_GDP_GROWTH_CEILING,
) -> TerminalValueResult:
    """Compute both terminal-value estimates and cross-validate them.

    Args:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Construct results via terminal_value(), not the dataclass
  2. Ensure growth < wacc before building (lower growth or raise WACC inputs)
  3. If hit via the public path, report it as a library bug with both values

Example fix

# before
TerminalValueResult(terminal_growth=Rate(0.08), wacc_rate=0.07, ...)

# after
terminal_value(terminal_year_ebitda=ebitda, wacc_rate=0.07, terminal_growth=Rate(0.05), ...)
Defensive patterns

Strategy: validation

Validate before calling

assert terminal_growth.value < wacc_rate, 'g must be < wacc'
result = terminal_value(...)  # not the dataclass directly

Type guard

def growth_below_wacc(g: float, w: float) -> bool:
    return g < w

Try / catch

try:
    TerminalValueResult(...)
except ValueError as e:
    raise AssertionError(f'do not construct directly; use terminal_value(): {e}') from e

Prevention

When it happens

Trigger: Manually constructing TerminalValueResult(terminal_growth=Rate(0.08), wacc_rate=0.07, ...); or mutating a result and revalidizing. If reached via terminal_value(), it indicates a validation-order bug in the library.

Common situations: Tests or adapters building the result object directly; library version skew between the guard in terminal_value() and this invariant.

Related errors


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