{"record":{"id":"d636f03723c88192","repo":"HKUDS/Vibe-Trading","slug":"fcff-bridge-ebit-forecast-is-empty-at-least-one","errorCode":null,"errorMessage":"fcff_bridge: ebit forecast is empty; at least one projection year is required","messagePattern":"fcff_bridge: ebit forecast is empty; at least one projection year is required","errorType":"validation","errorClass":"ValuationError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/dcf.py","lineNumber":611,"sourceCode":"            length as ``ebit``.\n        delta_nwc: Net-working-capital change forecast (positive = cash\n            outflow; see the module docstring), same length as ``ebit``.\n\n    Returns:\n        One :class:`FCFFYear` per projection year, in order.\n\n    Raises:\n        ValuationError: If ``tax_rate`` is outside ``[0, 1]``, if ``ebit`` is\n            empty, if the other three forecasts are not the same length as\n            ``ebit``, or if any forecast entry is not a finite number.\n    \"\"\"\n    if not 0.0 <= tax_rate <= 1.0:\n        raise ValuationError(f\"fcff_bridge: tax_rate must be within [0, 1], got {tax_rate!r}\")\n\n    ebit_list = list(ebit)\n    horizon = len(ebit_list)\n    if horizon == 0:\n        raise ValuationError(\n            \"fcff_bridge: ebit forecast is empty; at least one projection year \"\n            \"is required\"\n        )\n    forecasts = {\n        \"depreciation_amortization\": list(depreciation_amortization),\n        \"capex\": list(capex),\n        \"delta_nwc\": list(delta_nwc),\n    }\n    for name, values in forecasts.items():\n        if len(values) != horizon:\n            raise ValuationError(\n                f\"fcff_bridge: {name} has {len(values)} year(s), expected \"\n                f\"{horizon} to match ebit\"\n            )\n\n    years = []\n    for index in range(horizon):\n        ebit_value = _require_finite(ebit_list[index], f\"ebit[{index}]\", \"fcff_bridge\")","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/dcf.py#L593-L629","documentation":"fcff_bridge() requires at least one projection year; an empty ebit sequence raises ValuationError rather than returning an empty/zero result.","triggerScenarios":"fcff_bridge(ebit=[], depreciation_amortization=[], capex=[], delta_nwc=[]) — e.g. a filtered forecast frame that ended up with zero rows.","commonSituations":"Date-range filters or per-segment groupbys that legitimately produce zero rows; upstream data pull returning an empty frame for one ticker.","solutions":["Check len(ebit) > 0 before calling; skip or flag empty cases","Fix the upstream filter/join that dropped all forecast rows","If empty inputs are expected in your flow, branch to a non-DCF valuation path"],"exampleFix":"# before\nresult = fcff_bridge(ebit=df['ebit'], ...)\n\n# after\nif len(df) == 0:\n    raise ValueError(f'no forecast rows for {ticker}')\nresult = fcff_bridge(ebit=df['ebit'], ...)","handlingStrategy":"validation","validationCode":"if len(list(ebit)) == 0:\n    raise ValueError('no forecast years available')\nfcff_bridge(ebit=ebit, ...)","typeGuard":"def has_rows(seq) -> bool:\n    return len(list(seq)) > 0","tryCatchPattern":"try:\n    fcff_bridge(...)\nexcept ValuationError as e:\n    if 'empty' in str(e):\n        return None  # skip entity\n    raise","preventionTips":["Check row counts after filters/groupbys","Skip empty segments explicitly in batch jobs","Fail loudly on empty upstream data pulls"],"tags":["valuation","fcff","empty-input"],"backgroundTag":"empty-sequence-input","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}