{"record":{"id":"2f8eb112456eb99d","repo":"HKUDS/Vibe-Trading","slug":"scenario-iv-values-must-be-a-non-empty-array","errorCode":null,"errorMessage":"scenario_iv_values must be a non-empty array","messagePattern":"scenario_iv_values must be a non-empty array","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/options_payoff_tool.py","lineNumber":329,"sourceCode":"        raise ValueError(\"spot_min must be non-negative\")\n    if spot_max <= spot_min:\n        raise ValueError(\"spot_max must be greater than spot_min\")\n    return spot_min, spot_max\n\n\ndef _scenario_ivs(raw: Any, entry_iv: float) -> np.ndarray:\n    \"\"\"Resolve bounded explicit IV scenarios or the skill's five defaults.\"\"\"\n    if raw is None:\n        values = [\n            entry_iv * 0.5,\n            entry_iv * 0.75,\n            entry_iv,\n            entry_iv * 1.25,\n            entry_iv * 1.5,\n        ]\n    else:\n        if not isinstance(raw, list) or not raw:\n            raise ValueError(\"scenario_iv_values must be a non-empty array\")\n        if len(raw) > _MAX_IV_SCENARIOS:\n            raise ValueError(f\"scenario_iv_values may contain at most {_MAX_IV_SCENARIOS} entries\")\n        try:\n            values = [float(value) for value in raw]\n        except (TypeError, ValueError, OverflowError) as exc:\n            raise ValueError(\"scenario_iv_values must contain numbers\") from exc\n    array = np.asarray(values, dtype=float)\n    if not np.isfinite(array).all() or (array <= 0).any():\n        raise ValueError(\"scenario_iv_values must contain positive finite values\")\n    return array\n\n\ndef _rounded(value: float) -> float:\n    \"\"\"Round a finite scalar for stable, compact JSON.\"\"\"\n    return round(float(value), 6)\n\n\ndef _rounded_array(values: np.ndarray) -> list[float]:","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/options_payoff_tool.py#L311-L347","documentation":"Thrown by _scenario_ivs when the scenario_iv_values override is present but not a non-empty list. IV scenarios drive the volatility sensitivity rows; an empty array would produce an empty scenario table, so it is rejected. Omitting/null selects the five default scenarios (entry_iv multiples).","triggerScenarios":"scenario_iv_values=[] or a non-list such as \"0.2,0.3\" or {\"ivs\":[...]}. Only null/absence uses defaults.","commonSituations":"LLM passing comma strings instead of arrays; config templating producing empty lists when a filter removes all values; forwarding a dict from another schema.","solutions":["Pass a JSON array with at least one IV: [0.15, 0.25, 0.35]","Split string inputs: [float(x) for x in raw.split(',')] if non-empty","Omit the key to accept the default scenario ladder"],"exampleFix":"// before\nexecute({..., \"scenario_iv_values\": \"0.2,0.3\"})\n// after\nexecute({..., \"scenario_iv_values\": [0.2, 0.3]})","handlingStrategy":"validation","validationCode":"ivs = kwargs.get(\"scenario_iv_values\")\nif isinstance(ivs, str):\n    ivs = [float(x) for x in ivs.split(\",\") if x.strip()]\nif ivs is not None and (not isinstance(ivs, list) or not ivs):\n    ivs = None\nkwargs[\"scenario_iv_values\"] = ivs","typeGuard":"def iv_scenarios_ok(raw) -> bool:\n    return raw is None or (isinstance(raw, list) and len(raw) > 0)","tryCatchPattern":"try:\n    execute(kwargs)\nexcept ValueError as e:\n    if \"scenario_iv_values\" in str(e):\n        kwargs.pop(\"scenario_iv_values\", None); execute(kwargs)","preventionTips":["Always pass arrays, never comma-joined strings","Omit the key to use the default scenario ladder","Guard config templating against emitting empty lists"],"tags":["validation","options","volatility"],"backgroundTag":"schema-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}