{"record":{"id":"2272a113e593f485","repo":"HKUDS/Vibe-Trading","slug":"model-name-every-driver-sequence-must-share-one","errorCode":null,"errorMessage":"{MODEL_NAME}: every driver sequence must share one length (one entry per projected period); got {detail}","messagePattern":"(.+?): every driver sequence must share one length \\(one entry per projected period\\); got (.+?)","errorType":"validation","errorClass":"ValuationError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/threestatement.py","lineNumber":495,"sourceCode":"def _resolve_period_count(drivers: Mapping[str, Sequence[float]]) -> int:\n    \"\"\"Validate every driver sequence shares one non-zero length and return it.\n\n    Args:\n        drivers: The driver mapping already checked by\n            :func:`~src.quantlib.valuation.contracts.require_inputs`.\n\n    Returns:\n        The number of periods to project.\n\n    Raises:\n        ValuationError: If the driver sequences disagree in length, or all are\n            empty.\n    \"\"\"\n    lengths = {field: len(drivers[field]) for field in DRIVER_REQUIRED_FIELDS}\n    distinct = set(lengths.values())\n    if len(distinct) > 1:\n        detail = \", \".join(f\"{field}={n}\" for field, n in lengths.items())\n        raise ValuationError(\n            f\"{MODEL_NAME}: every driver sequence must share one length (one entry \"\n            f\"per projected period); got {detail}\"\n        )\n    periods = distinct.pop()\n    if periods < 1:\n        raise ValuationError(\n            f\"{MODEL_NAME}: driver sequences are empty; at least one projection \"\n            \"period is required\"\n        )\n    return periods\n\n\ndef _project_period(\n    period: int,\n    prior_bs: BalanceSheet,\n    prior_revenue: float,\n    revenue_growth: float,\n    gross_margin: float,","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/threestatement.py#L477-L513","documentation":"project_three_statement requires every driver sequence (revenue growth, margins, capex, etc. — DRIVER_REQUIRED_FIELDS) to have the same length, one entry per projected period. If lengths differ, _resolve_period_count raises ValuationError listing each field and its length so you can see which array is short or long.","triggerScenarios":"Passing a drivers dict where, say, revenue_growth has 5 entries but capex_pct has 4 — typically from slicing different date ranges or appending to one list and forgetting another.","commonSituations":"Drivers assembled from multiple spreadsheets/DataFrames with mismatched horizons; extending the forecast horizon for some lines only; off-by-one when adding a stub period.","solutions":["Compare the per-field lengths in the message and re-slice/re-extend the offending arrays to a common horizon.","Build all driver arrays from one shared periods index (e.g. one DataFrame column per field).","Assert equal lengths in a helper before calling project_three_statement."],"exampleFix":"# before\ndrivers = {\"revenue_growth\": [0.1]*5, \"capex_pct\": [0.03]*4, ...}\n# after\nn = 5\ndrivers = {\"revenue_growth\": [0.1]*n, \"capex_pct\": [0.03]*n, ...}","handlingStrategy":"validation","validationCode":"lengths = {len(v) for v in drivers.values()}\nassert len(lengths) == 1, f'driver lengths diverge: {lengths}'","typeGuard":"def drivers_aligned(drivers) -> bool:\n    return len({len(v) for v in drivers.values()}) == 1","tryCatchPattern":"except ValuationError as e:\n    if 'share one length' in str(e): parse_lengths_and_reslice(e)","preventionTips":["Derive all driver columns from one shared forecast index","Extend horizons by regenerating, not by appending to individual lists"],"tags":["valuation","three-statement","shape-mismatch","drivers"],"backgroundTag":"length-mismatch","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}