{"record":{"id":"4e5d36f0baff716f","repo":"HKUDS/Vibe-Trading","slug":"valuations-must-be-an-array-of-at-least-two-date","errorCode":null,"errorMessage":"valuations must be an array of at least two {date, value} objects","messagePattern":"valuations must be an array of at least two (.+?) objects","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/cashflow_analytics_tool.py","lineNumber":317,"sourceCode":"        }\n        return json.dumps(payload, ensure_ascii=False, allow_nan=False)\n\n\ndef _coerce_valuations(raw: Any) -> list[tuple[date, float]]:\n    \"\"\"Parse the raw valuation array into ``(date, value)`` pairs.\n\n    Args:\n        raw: Value supplied for the ``valuations`` parameter.\n\n    Returns:\n        Pairs in the order supplied; the library sorts and validates them.\n\n    Raises:\n        ValueError: If the array is missing, wrongly shaped, over the size cap,\n            or an entry lacks a usable date or value.\n    \"\"\"\n    if not isinstance(raw, list) or len(raw) < 2:\n        raise ValueError(\"valuations must be an array of at least two {date, value} objects\")\n    if len(raw) > _MAX_VALUATIONS:\n        raise ValueError(f\"valuations may contain at most {_MAX_VALUATIONS} entries\")\n\n    pairs: list[tuple[date, float]] = []\n    for index, item in enumerate(raw):\n        if not isinstance(item, dict):\n            raise ValueError(f\"valuations[{index}] must be an object with date and value\")\n        if \"date\" not in item or \"value\" not in item:\n            raise ValueError(f\"valuations[{index}] needs both 'date' and 'value'\")\n        try:\n            value = float(item[\"value\"])\n        except (TypeError, ValueError) as exc:\n            raise ValueError(f\"valuations[{index}].value must be numeric\") from exc\n        if not math.isfinite(value):\n            raise ValueError(f\"valuations[{index}].value must be finite\")\n        pairs.append((item[\"date\"], value))\n    return pairs\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/cashflow_analytics_tool.py#L299-L335","documentation":"_coerce_valuations in cashflow_analytics_tool requires the valuations argument to be a JSON array with at least two {date, value} entries; a single point, a non-list, or a missing value cannot define a return series.","triggerScenarios":"Calling execute with valuations=[{...}] (one point), a dict, a JSON string of an array, or omitting the argument.","commonSituations":"LLM emitting a bare object instead of an array; JSON-encoded strings passed unparsed; test fixtures with a single sample point.","solutions":["Pass at least two {date, value} dicts in an actual list","json.loads the payload first if it arrives as a string","Enforce minItems:2 in the tool's JSON schema"],"exampleFix":"// before\nvaluations=[{'date': '2024-01-01', 'value': 100}]\n// after\nvaluations=[{'date': '2024-01-01', 'value': 100}, {'date': '2024-06-30', 'value': 108}]","handlingStrategy":"validation","validationCode":"valuations = json.loads(valuations) if isinstance(valuations, str) else valuations\nassert isinstance(valuations, list) and len(valuations) >= 2","typeGuard":"def is_valuations_array(v: object) -> bool:\n    return isinstance(v, list) and len(v) >= 2 and all(isinstance(i, dict) for i in v)","tryCatchPattern":"try:\n    tool.execute(valuations=valuations)\nexcept ValueError as e:\n    if 'at least two' in str(e):\n        raise UserInputError('provide >= 2 valuation points')","preventionTips":["Set minItems:2 and type:array in the tool schema","Parse JSON strings before passing them as arrays"],"tags":["validation","api-parameters","cashflow-analytics"],"backgroundTag":"schema-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}