{"record":{"id":"78692ff145223c1a","repo":"HKUDS/Vibe-Trading","slug":"valuations-index-must-have-exactly-two-elements","errorCode":null,"errorMessage":"valuations[{index}] must have exactly two elements (date, value), got {len(pair)}","messagePattern":"valuations\\[(.+?)\\] must have exactly two elements \\(date, value\\), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/performance.py","lineNumber":314,"sourceCode":"    Raises:\n        ValueError: If fewer than two valuations were supplied, a pair is\n            malformed, a value is not finite, or a date repeats. A repeated\n            date is rejected rather than deduplicated because two different\n            marks for one day have no defensible ordering.\n    \"\"\"\n    if isinstance(valuations, Mapping):\n        raw_items: list[tuple[object, object]] = list(valuations.items())\n    else:\n        raw_items = []\n        for index, item in enumerate(valuations):\n            if isinstance(item, (str, bytes)) or not isinstance(item, Sequence):\n                raise ValueError(\n                    f\"valuations[{index}] must be a (date, value) pair, got \"\n                    f\"{type(item).__name__}\"\n                )\n            pair = tuple(item)\n            if len(pair) != 2:\n                raise ValueError(\n                    f\"valuations[{index}] must have exactly two elements \"\n                    f\"(date, value), got {len(pair)}\"\n                )\n            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(","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/performance.py#L296-L332","documentation":"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.","triggerScenarios":"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.","commonSituations":"itertuples() rows including the pandas index; denormalised rows carrying extra metadata; refactoring from dicts to tuples and leaving stray fields.","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."],"exampleFix":"# before\nvals = list(df.itertuples())  # (Index, Date, Value) -> len 3, raises\n\n# after\nvals = list(df[['date', 'value']].itertuples(index=False, name=None))  # len 2","handlingStrategy":"type-guard","validationCode":"vals = [(d, v) for d, v, *_ in rows]  # or slice: [(r[0], r[1]) for r in rows]","typeGuard":"def all_pairs_len_two(v) -> bool:\n    return all(len(tuple(i)) == 2 for i in v if isinstance(i, (list, tuple)))","tryCatchPattern":"try:\n    r = time_weighted_return(valuations)\nexcept ValueError as e:\n    if 'exactly two elements' in str(e):\n        r = time_weighted_return([(x[0], x[1]) for x in valuations])\n    else:\n        raise","preventionTips":["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."],"tags":["performance","valuation","input-validation","tuple-length"],"backgroundTag":"invalid-argument-structure","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}