{"record":{"id":"c00efc53e01f20e4","repo":"HKUDS/Vibe-Trading","slug":"valuation-on-when-must-be-finite-got-raw-value","errorCode":null,"errorMessage":"valuation on {when} must be finite, got {raw_value!r}; a missing mark must be fixed at the source, not carried as NaN","messagePattern":"valuation on (.+?) must be finite, got (.+?); a missing mark must be fixed at the source, not carried as NaN","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/performance.py","lineNumber":336,"sourceCode":"            raw_items.append((pair[0], pair[1]))\n\n    if len(raw_items) < 2:\n        raise ValueError(\n            \"a return needs an opening and a closing valuation; got \"\n            f\"{len(raw_items)}\"\n        )\n\n    resolved: list[tuple[date, float]] = []\n    for raw_date, raw_value in raw_items:\n        when = normalize_date(raw_date, field_name=\"valuation date\")\n        try:\n            value = float(raw_value)\n        except (TypeError, ValueError) as exc:\n            raise ValueError(\n                f\"valuation on {when} must be numeric, got {raw_value!r}\"\n            ) from exc\n        if not math.isfinite(value):\n            raise ValueError(\n                f\"valuation on {when} must be finite, got {raw_value!r}; a \"\n                \"missing mark must be fixed at the source, not carried as NaN\"\n            )\n        resolved.append((when, value))\n\n    resolved.sort(key=lambda item: item[0])\n    for earlier, later in zip(resolved, resolved[1:], strict=False):\n        if earlier[0] == later[0]:\n            raise ValueError(\n                f\"two valuations share the date {earlier[0]}; a single day can \"\n                \"carry only one mark\"\n            )\n    return tuple(resolved)\n\n\ndef external_flows(\n    flows: CashFlowSeries | Iterable[CashFlow] | None,\n    *,","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/performance.py#L318-L354","documentation":"After a successful float() conversion, _normalize_valuations rejects non-finite values (NaN, +inf, -inf). A NaN mark would silently propagate through the return chain (NaN returns, NaN TWR), and infinities are impossible portfolio values, so the library demands the fix happen at the data source — the message says exactly that.","triggerScenarios":"Passing float('nan') as a value (e.g. from pd.to_numeric(errors='coerce') on dirty data, or numpy operations producing NaN), or inf from a division by zero in upstream mark calculations.","commonSituations":"pandas coercion of empty/parsing-failed cells to NaN; joins introducing NaN for missing dates then itertuples feeding them in; zero-division in a derived per-unit value; SQL NULLs converted to NaN rather than dropped.","solutions":["Drop or repair NaN marks at the source: df = df.dropna(subset=[value_col]) or re-fetch the price.","Do not use pd.to_numeric(errors='coerce') blindly on data destined for valuations — surface errors instead.","Add assert all(math.isfinite(v) for _, v in marks) in ingestion tests."],"exampleFix":"# before\nmarks = list(df[['date', 'value']].itertuples(index=False, name=None))  # may contain NaN\ntwr = time_weighted_return(marks)  # raises on NaN\n\n# after\nmarks = list(df.dropna(subset=['value'])[['date', 'value']].itertuples(index=False, name=None))\ntwr = time_weighted_return(marks)","handlingStrategy":"validation","validationCode":"import math\nclean = [(d, float(v)) for d, v in valuations if math.isfinite(float(v))]","typeGuard":"def all_values_finite(vals) -> bool:\n    return all(math.isfinite(float(v)) for _, v in vals)","tryCatchPattern":"try:\n    r = time_weighted_return(valuations)\nexcept ValueError as e:\n    if 'must be finite' in str(e):\n        raise DataQualityError(f'non-finite mark: {e}') from e\n    raise","preventionTips":["Avoid pd.to_numeric(errors='coerce') on valuation columns; use raise.","dropna(subset=[value_col]) before building the pair list.","Assert finiteness in ingestion tests."],"tags":["performance","valuation","nan","data-quality"],"backgroundTag":"non-finite-input-value","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}