{"record":{"id":"027089e59b56b3cd","repo":"HKUDS/Vibe-Trading","slug":"fcff-bridge-name-has-len-values-year-s-exp","errorCode":null,"errorMessage":"fcff_bridge: {name} has {len(values)} year(s), expected {horizon} to match ebit","messagePattern":"fcff_bridge: (.+?) has (.+?) year\\(s\\), expected (.+?) to match ebit","errorType":"validation","errorClass":"ValuationError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/dcf.py","lineNumber":622,"sourceCode":"    \"\"\"\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\")\n        da_value = _require_finite(\n            forecasts[\"depreciation_amortization\"][index],\n            f\"depreciation_amortization[{index}]\",\n            \"fcff_bridge\",\n        )\n        capex_value = _require_finite(\n            forecasts[\"capex\"][index], f\"capex[{index}]\", \"fcff_bridge\"\n        )\n        delta_nwc_value = _require_finite(\n            forecasts[\"delta_nwc\"][index], f\"delta_nwc[{index}]\", \"fcff_bridge\"\n        )","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/dcf.py#L604-L640","documentation":"fcff_bridge() requires depreciation_amortization, capex and delta_nwc to have exactly the same length as ebit; otherwise a ValuationError names the mismatched series and its length.","triggerScenarios":"Passing a 5-year ebit with a 4-year capex list; a scalar or single D&A value broadcast by hand to the wrong length; misaligned DataFrame slices.","commonSituations":"Horizon extended for ebit but not for other assumptions; pandas series aligned on different indices silently producing different lengths after dropna.","solutions":["Align all four series to the same horizon/length before calling (assert equal lengths)","When extending the forecast horizon, update all assumption rows together","If using pandas, reset/reindex all series on a common positional index before list()"],"exampleFix":"# before\nfcff_bridge(ebit=df['ebit'], capex=df['capex'].dropna(), ...)\n\n# after\ncapex = df['capex'].reindex(df['ebit'].index).fillna(0.0)\nfcff_bridge(ebit=df['ebit'], capex=capex, ...)","handlingStrategy":"validation","validationCode":"n = len(list(ebit))\nassert all(len(list(x)) == n for x in (da, capex, dnwc)), 'length mismatch'\nfcff_bridge(ebit=ebit, depreciation_amortization=da, capex=capex, delta_nwc=dnwc)","typeGuard":"def same_length(*seqs) -> bool:\n    n = len(list(seqs[0]))\n    return all(len(list(s)) == n for s in seqs)","tryCatchPattern":"try:\n    fcff_bridge(...)\nexcept ValuationError as e:\n    if 'expected' in str(e):\n        raise DataAlignmentError(str(e)) from e\n    raise","preventionTips":["Extend all assumption series together when changing horizon","Reindex pandas series on a common positional index before list()","Assert equal lengths in a pre-flight check"],"tags":["valuation","fcff","length-mismatch","alignment"],"backgroundTag":"sequence-length-mismatch","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}