{"record":{"id":"b0616aba8a476650","repo":"HKUDS/Vibe-Trading","slug":"spot-points-must-be-an-integer","errorCode":null,"errorMessage":"spot_points must be an integer","messagePattern":"spot_points must be an integer","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/options_payoff_tool.py","lineNumber":290,"sourceCode":"    \"\"\"Read an optional finite float, treating null and empty text as omitted.\"\"\"\n    raw = kwargs.get(name)\n    if raw is None or raw == \"\":\n        return default\n    try:\n        value = float(raw)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be numeric\") from exc\n    if not math.isfinite(value):\n        raise ValueError(f\"{name} must be finite\")\n    return value\n\n\ndef _spot_points(raw: Any) -> int:\n    \"\"\"Validate the bounded display-grid size.\"\"\"\n    if raw is None or raw == \"\":\n        return _DEFAULT_SPOT_POINTS\n    if isinstance(raw, bool):\n        raise ValueError(\"spot_points must be an integer\")\n    try:\n        numeric = float(raw)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(\"spot_points must be an integer\") from exc\n    if not math.isfinite(numeric) or not numeric.is_integer():\n        raise ValueError(\"spot_points must be an integer\")\n    points = int(numeric)\n    if not _MIN_SPOT_POINTS <= points <= _MAX_SPOT_POINTS:\n        raise ValueError(f\"spot_points must be between {_MIN_SPOT_POINTS} and {_MAX_SPOT_POINTS}\")\n    return points\n\n\ndef _spot_bounds(kwargs: dict[str, Any], legs: list[OptionLeg], entry_spot: float) -> tuple[float, float]:\n    \"\"\"Resolve explicit chart bounds or safe defaults covering every strike.\"\"\"\n    reference = [entry_spot, *(leg.strike for leg in legs)]\n    default_min = max(min(reference) * 0.5, 0.0)\n    default_max = max(reference) * 1.5\n    spot_min = _optional_float(kwargs, \"spot_min\", default_min)","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/options_payoff_tool.py#L272-L308","documentation":"Thrown by _spot_points when the display-grid size parameter is a Python bool. Because bool subclasses int and float(True)==1.0 would pass numeric checks, the tool explicitly rejects booleans first. spot_points controls chart resolution and must be a whole number.","triggerScenarios":"spot_points=True/False, typically from a config flag miswired into the parameter, or JSON true/false where a count was expected.","commonSituations":"Config schemas reusing a generic 'points' flag; LLM filling booleans into numeric slots; toggles accidentally bound to the wrong key.","solutions":["Pass an integer count like 50 or 200","Rename/retype the config field that feeds spot_points","Omit it to use _DEFAULT_SPOT_POINTS"],"exampleFix":"// before\nexecute({..., \"spot_points\": True})\n// after\nexecute({..., \"spot_points\": 100})","handlingStrategy":"type-guard","validationCode":"if isinstance(kwargs.get(\"spot_points\"), bool):\n    raise TypeError(\"spot_points must be an int, got bool\")","typeGuard":"def spot_points_ok(v) -> bool:\n    return v is None or (isinstance(v, int) and not isinstance(v, bool))","tryCatchPattern":"try:\n    execute(kwargs)\nexcept ValueError as e:\n    if \"spot_points\" in str(e):\n        kwargs.pop(\"spot_points\", None); execute(kwargs)","preventionTips":["Type config fields explicitly as int","Never reuse boolean toggles for count parameters","Add JSON-schema type:integer for spot_points"],"tags":["validation","boolean-vs-number","options"],"backgroundTag":"wrong-parameter-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}