HKUDS/Vibe-Trading · error · ValueError
valuations[{index}] must have exactly two elements (date, va
Error message
valuations[{index}] must have exactly two elements (date, value), got {len(pair)} What it means
When a valuations element is a sequence, _normalize_valuations requires it to hold exactly two items — the date and the value. Longer or shorter tuples are ambiguous (a 3-tuple cannot be a date/value pair) and are rejected with the actual length reported.
Source
Thrown at agent/src/quantlib/performance.py:314
Raises:
ValueError: If fewer than two valuations were supplied, a pair is
malformed, a value is not finite, or a date repeats. A repeated
date is rejected rather than deduplicated because two different
marks for one day have no defensible ordering.
"""
if isinstance(valuations, Mapping):
raw_items: list[tuple[object, object]] = list(valuations.items())
else:
raw_items = []
for index, item in enumerate(valuations):
if isinstance(item, (str, bytes)) or not isinstance(item, Sequence):
raise ValueError(
f"valuations[{index}] must be a (date, value) pair, got "
f"{type(item).__name__}"
)
pair = tuple(item)
if len(pair) != 2:
raise ValueError(
f"valuations[{index}] must have exactly two elements "
f"(date, value), got {len(pair)}"
)
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(View on GitHub (pinned to 80ffdda44c)
Solutions
- Slice to two: [(r[0], r[1]) for r in rows] or use df[[date_col, value_col]].itertuples(index=False, name=None).
- Strip metadata into a separate structure keyed by date.
- Add a quick length assertion during data prep.
Example fix
# before vals = list(df.itertuples()) # (Index, Date, Value) -> len 3, raises # after vals = list(df[['date', 'value']].itertuples(index=False, name=None)) # len 2
Defensive patterns
Strategy: type-guard
Validate before calling
vals = [(d, v) for d, v, *_ in rows] # or slice: [(r[0], r[1]) for r in rows]
Type guard
def all_pairs_len_two(v) -> bool:
return all(len(tuple(i)) == 2 for i in v if isinstance(i, (list, tuple))) Try / catch
try:
r = time_weighted_return(valuations)
except ValueError as e:
if 'exactly two elements' in str(e):
r = time_weighted_return([(x[0], x[1]) for x in valuations])
else:
raise Prevention
- Use itertuples(index=False, name=None) with exactly two selected columns.
- Keep metadata out of valuation tuples; key extras by date.
- Assert pair length in ingestion.
When it happens
Trigger: Passing [('2024-01-01', 100.0, 'USD'), ...] with a currency attached, or a list of rows taken from a DataFrame via df.itertuples() that includes an index element, or a leftover (date, value, note) debug field.
Common situations: itertuples() rows including the pandas index; denormalised rows carrying extra metadata; refactoring from dicts to tuples and leaving stray fields.
Related errors
- valuations[{index}] must be a (date, value) pair, got {type(
- a return needs an opening and a closing valuation; got {len(
- valuation on {when} must be numeric, got {raw_value!r}
- valuation on {when} must be finite, got {raw_value!r}; a mis
- {model}: {name} must be a finite number, got {val!r}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/78692ff145223c1a.
Report an issue: GitHub.