HKUDS/Vibe-Trading · error · ValueError
valuation on {when} must be finite, got {raw_value!r}; a mis
Error message
valuation on {when} must be finite, got {raw_value!r}; a missing mark must be fixed at the source, not carried as NaN What it means
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.
Source
Thrown at agent/src/quantlib/performance.py:336
raw_items.append((pair[0], pair[1]))
if len(raw_items) < 2:
raise ValueError(
"a return needs an opening and a closing valuation; got "
f"{len(raw_items)}"
)
resolved: list[tuple[date, float]] = []
for raw_date, raw_value in raw_items:
when = normalize_date(raw_date, field_name="valuation date")
try:
value = float(raw_value)
except (TypeError, ValueError) as exc:
raise ValueError(
f"valuation on {when} must be numeric, got {raw_value!r}"
) from exc
if not math.isfinite(value):
raise ValueError(
f"valuation on {when} must be finite, got {raw_value!r}; a "
"missing mark must be fixed at the source, not carried as NaN"
)
resolved.append((when, value))
resolved.sort(key=lambda item: item[0])
for earlier, later in zip(resolved, resolved[1:], strict=False):
if earlier[0] == later[0]:
raise ValueError(
f"two valuations share the date {earlier[0]}; a single day can "
"carry only one mark"
)
return tuple(resolved)
def external_flows(
flows: CashFlowSeries | Iterable[CashFlow] | None,
*,View on GitHub (pinned to 80ffdda44c)
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.
Example fix
# before marks = list(df[['date', 'value']].itertuples(index=False, name=None)) # may contain NaN twr = time_weighted_return(marks) # raises on NaN # after marks = list(df.dropna(subset=['value'])[['date', 'value']].itertuples(index=False, name=None)) twr = time_weighted_return(marks)
Defensive patterns
Strategy: validation
Validate before calling
import math clean = [(d, float(v)) for d, v in valuations if math.isfinite(float(v))]
Type guard
def all_values_finite(vals) -> bool:
return all(math.isfinite(float(v)) for _, v in vals) Try / catch
try:
r = time_weighted_return(valuations)
except ValueError as e:
if 'must be finite' in str(e):
raise DataQualityError(f'non-finite mark: {e}') from e
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- valuation on {when} must be numeric, got {raw_value!r}
- index level on {day} is {raw_level!r}; index levels must be
- valuations[{index}] must be a (date, value) pair, got {type(
- valuations[{index}] must have exactly two elements (date, va
- a return needs an opening and a closing valuation; got {len(
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/c00efc53e01f20e4.
Report an issue: GitHub.