{"record":{"id":"0be49f32aaf4af16","repo":"HKUDS/Vibe-Trading","slug":"legs-index-has-invalid-strike-or-qty-exc","errorCode":null,"errorMessage":"legs[{index}] has invalid strike or qty: {exc}","messagePattern":"legs\\[(.+?)\\] has invalid strike or qty: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/options_payoff_tool.py","lineNumber":245,"sourceCode":"\ndef _coerce_legs(raw: Any) -> list[OptionLeg]:\n    \"\"\"Parse and validate raw JSON-style leg objects.\"\"\"\n    if not isinstance(raw, list) or not raw:\n        raise ValueError(\"legs must be a non-empty array\")\n    if len(raw) > _MAX_LEGS:\n        raise ValueError(f\"legs may contain at most {_MAX_LEGS} entries\")\n\n    legs: list[OptionLeg] = []\n    for index, item in enumerate(raw):\n        if not isinstance(item, dict):\n            raise ValueError(f\"legs[{index}] must be an object\")\n        option_type = str(item.get(\"option_type\") or \"\").strip().lower()\n        try:\n            strike = float(item[\"strike\"])\n            raw_qty = item[\"qty\"]\n            qty_number = float(raw_qty)\n        except (KeyError, TypeError, ValueError, OverflowError) as exc:\n            raise ValueError(f\"legs[{index}] has invalid strike or qty: {exc}\") from exc\n        if isinstance(raw_qty, bool) or not qty_number.is_integer():\n            raise ValueError(f\"legs[{index}].qty must be a non-zero integer\")\n        qty = int(qty_number)\n        raw_premium = item.get(\"premium\")\n        try:\n            premium = None if raw_premium is None else float(raw_premium)\n        except (TypeError, ValueError, OverflowError) as exc:\n            raise ValueError(f\"legs[{index}].premium must be numeric or null\") from exc\n        legs.append(OptionLeg(option_type, strike, qty, premium))\n    return legs\n\n\ndef _required_float(kwargs: dict[str, Any], name: str) -> float:\n    \"\"\"Read a required finite float.\"\"\"\n    if name not in kwargs or kwargs[name] is None or kwargs[name] == \"\":\n        raise ValueError(f\"{name} is required\")\n    try:\n        value = float(kwargs[name])","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/options_payoff_tool.py#L227-L263","documentation":"Thrown when a leg's strike or qty fails numeric conversion — the key is missing (KeyError), the value is a non-numeric string/list (TypeError/ValueError), or an enormous number overflows float conversion. The chained exception message carries the underlying conversion error.","triggerScenarios":"leg missing the strike or qty key; strike=\"abc\"; qty=[1]; qty=1e400 in raw text; qty=None. e.g. {\"option_type\":\"call\",\"strike\":100} (no qty) triggers it.","commonSituations":"Handwritten JSON with typos or omitted fields; LLM-generated legs that drop qty; string numbers with currency symbols or commas (\"1,000\").","solutions":["Ensure both strike and qty are present and numeric (strings like \"100.5\" are fine)","Strip currency/separator formatting before passing: float(raw.replace(',',''))","If fields come from user input, coerce and validate them in your own schema first"],"exampleFix":"// before\n{\"option_type\": \"call\", \"strike\": \"100 USD\", \"qty\": \"1\"}\n// after\n{\"option_type\": \"call\", \"strike\": 100.0, \"qty\": 1}","handlingStrategy":"validation","validationCode":"for leg in legs:\n    for k in (\"strike\", \"qty\"):\n        try:\n            float(leg[k])\n        except (KeyError, TypeError, ValueError):\n            raise ValueError(f\"leg field {k} missing/non-numeric: {leg}\")","typeGuard":"def leg_numerics_ok(leg: dict) -> bool:\n    try:\n        float(leg[\"strike\"]); float(leg[\"qty\"])\n        return True\n    except (KeyError, TypeError, ValueError, OverflowError):\n        return False","tryCatchPattern":"try:\n    execute(kwargs)\nexcept ValueError as e:\n    if \"invalid strike or qty\" in str(e):\n        highlight_bad_leg_to_user(e)","preventionTips":["Type legs with pydantic (strike: float, qty: int)","Sanitize number strings (strip commas/symbols) at ingestion","Log raw leg payloads on failure for diagnosis"],"tags":["validation","options","type-coercion"],"backgroundTag":"numeric-field-invalid","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}