HKUDS/Vibe-Trading · error · ValuationError

fcff_bridge: tax_rate must be within [0, 1], got {tax_rate!r

Error message

fcff_bridge: tax_rate must be within [0, 1], got {tax_rate!r}

What it means

fcff_bridge() validates tax_rate as a fraction in [0, 1] before building forecast years; percent values, negatives, or >1 are rejected with ValuationError.

Source

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

    Args:
        ebit: EBIT forecast, one entry per projection year, oldest first.
        tax_rate: Marginal tax rate in ``[0, 1]``, applied to every year.
        depreciation_amortization: D&A forecast, same length as ``ebit``.
        capex: Capital expenditure forecast (positive = cash outflow), same
            length as ``ebit``.
        delta_nwc: Net-working-capital change forecast (positive = cash
            outflow; see the module docstring), same length as ``ebit``.

    Returns:
        One :class:`FCFFYear` per projection year, in order.

    Raises:
        ValuationError: If ``tax_rate`` is outside ``[0, 1]``, if ``ebit`` is
            empty, if the other three forecasts are not the same length as
            ``ebit``, or if any forecast entry is not a finite number.
    """
    if not 0.0 <= tax_rate <= 1.0:
        raise ValuationError(f"fcff_bridge: tax_rate must be within [0, 1], got {tax_rate!r}")

    ebit_list = list(ebit)
    horizon = len(ebit_list)
    if horizon == 0:
        raise ValuationError(
            "fcff_bridge: ebit forecast is empty; at least one projection year "
            "is required"
        )
    forecasts = {
        "depreciation_amortization": list(depreciation_amortization),
        "capex": list(capex),
        "delta_nwc": list(delta_nwc),
    }
    for name, values in forecasts.items():
        if len(values) != horizon:
            raise ValuationError(
                f"fcff_bridge: {name} has {len(values)} year(s), expected "
                f"{horizon} to match ebit"

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Convert percent to fraction: tax_rate/100
  2. Clamp computed effective rates to [0,1] or decide policy for negative rates before calling
  3. Centralize unit conversion for all rate inputs (tax, growth, discount) at the config layer

Example fix

# before
fcff_bridge(tax_rate=21, ...)

# after
fcff_bridge(tax_rate=0.21, ...)
Defensive patterns

Strategy: validation

Validate before calling

assert 0.0 <= tax_rate <= 1.0, 'tax_rate must be a fraction'
fcff_bridge(tax_rate=tax_rate, ...)

Type guard

def is_fraction(x) -> TypeGuard[float]:
    return isinstance(x, (int, float)) and 0.0 <= x <= 1.0

Try / catch

try:
    fcff_bridge(...)
except ValuationError as e:
    if 'tax_rate' in str(e):
        return fcff_bridge(tax_rate=tax_rate / 100, ...)
    raise

Prevention

When it happens

Trigger: fcff_bridge(tax_rate=21, ebit=[...]) with percent instead of 0.21; negative effective tax rates from credit-heavy financials passed unclamped.

Common situations: Same percent-vs-fraction class of mistake as wacc; tax rates sourced from statements as integers.

Related errors


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