{"record":{"id":"04efd930b0aeb252","repo":"HKUDS/Vibe-Trading","slug":"model-name-must-be-a-number-got-value-r-04efd9","errorCode":null,"errorMessage":"{model}: {name} must be a number, got {value!r}","messagePattern":"(.+?): (.+?) must be a number, got (.+?)","errorType":"validation","errorClass":"ValuationError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/threestatement.py","lineNumber":469,"sourceCode":"    \"\"\"Check a value is a finite number, refusing NaN and infinity.\n\n    Args:\n        value: The candidate value.\n        name: Field name for the error message.\n        model: Model name for the error message.\n\n    Returns:\n        ``value`` as a float.\n\n    Raises:\n        ValuationError: If the value is not a finite number. A non-finite\n            driver or opening figure would otherwise flow into the projection\n            and surface as a misleading \"did not converge\" error.\n    \"\"\"\n    try:\n        numeric = float(value)\n    except (TypeError, ValueError) as exc:\n        raise ValuationError(f\"{model}: {name} must be a number, got {value!r}\") from exc\n    if not math.isfinite(numeric):\n        raise ValuationError(\n            f\"{model}: {name} must be a finite number, got {numeric!r}\"\n        )\n    return numeric\n\n\ndef _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:","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/threestatement.py#L451-L487","documentation":"_require_finite coerces every opening figure and driver to float before projecting; if float(value) raises TypeError/ValueError (string like 'n/a', None, a list) it raises ValuationError naming the model and field. This stops non-numeric inputs from propagating into the solver and surfacing later as a confusing convergence failure.","triggerScenarios":"Calling project_three_statement with an opening dict or drivers mapping containing None, a non-numeric string, or a nested sequence where a scalar is expected — e.g. opening['cash'] = None from a pandas extraction.","commonSituations":"Loading drivers from YAML/CSV where empty cells become None or ''; JSON configs with stringly-typed numbers; dict keys from pandas rows returning objects.","solutions":["Find the field named in the message and convert it to a real number (float/int).","Clean the source data: fill/replace empty or string values with numeric ones before building the dicts.","Add a pass over opening/drivers with a numeric type check before calling project_three_statement."],"exampleFix":"# before\nopening = {\"cash\": None, ...}\nproject_three_statement(opening, drivers)\n# after\nopening = {\"cash\": 0.0, ...}  # or float(df.iloc[0]['cash']) after cleaning\nproject_three_statement(opening, drivers)","handlingStrategy":"validation","validationCode":"for k, v in {**opening, **{f: x for f, xs in drivers.items() for x in [xs]}}.items():\n    float(v)  # raises early with your own context","typeGuard":"def all_numeric(mapping) -> bool:\n    try:\n        [float(v) for v in mapping.values()]\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"except ValuationError as e:\n    if 'must be a number' in str(e): clean_inputs_and_report(e)","preventionTips":["Coerce and validate driver/opening values at the data-loading boundary","Never pass raw pandas cells or YAML scalars unchecked"],"tags":["valuation","three-statement","type-coercion","invalid-argument"],"backgroundTag":"non-numeric-input","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}