HKUDS/Vibe-Trading · error · ValueError
spot_points must be an integer
Error message
spot_points must be an integer
What it means
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.
Source
Thrown at agent/src/tools/options_payoff_tool.py:290
"""Read an optional finite float, treating null and empty text as omitted."""
raw = kwargs.get(name)
if raw is None or raw == "":
return default
try:
value = float(raw)
except (TypeError, ValueError, OverflowError) as exc:
raise ValueError(f"{name} must be numeric") from exc
if not math.isfinite(value):
raise ValueError(f"{name} must be finite")
return value
def _spot_points(raw: Any) -> int:
"""Validate the bounded display-grid size."""
if raw is None or raw == "":
return _DEFAULT_SPOT_POINTS
if isinstance(raw, bool):
raise ValueError("spot_points must be an integer")
try:
numeric = float(raw)
except (TypeError, ValueError, OverflowError) as exc:
raise ValueError("spot_points must be an integer") from exc
if not math.isfinite(numeric) or not numeric.is_integer():
raise ValueError("spot_points must be an integer")
points = int(numeric)
if not _MIN_SPOT_POINTS <= points <= _MAX_SPOT_POINTS:
raise ValueError(f"spot_points must be between {_MIN_SPOT_POINTS} and {_MAX_SPOT_POINTS}")
return points
def _spot_bounds(kwargs: dict[str, Any], legs: list[OptionLeg], entry_spot: float) -> tuple[float, float]:
"""Resolve explicit chart bounds or safe defaults covering every strike."""
reference = [entry_spot, *(leg.strike for leg in legs)]
default_min = max(min(reference) * 0.5, 0.0)
default_max = max(reference) * 1.5
spot_min = _optional_float(kwargs, "spot_min", default_min)View on GitHub (pinned to 80ffdda44c)
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
Example fix
// before
execute({..., "spot_points": True})
// after
execute({..., "spot_points": 100}) Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(kwargs.get("spot_points"), bool):
raise TypeError("spot_points must be an int, got bool") Type guard
def spot_points_ok(v) -> bool:
return v is None or (isinstance(v, int) and not isinstance(v, bool)) Try / catch
try:
execute(kwargs)
except ValueError as e:
if "spot_points" in str(e):
kwargs.pop("spot_points", None); execute(kwargs) Prevention
- Type config fields explicitly as int
- Never reuse boolean toggles for count parameters
- Add JSON-schema type:integer for spot_points
When it happens
Trigger: spot_points=True/False, typically from a config flag miswired into the parameter, or JSON true/false where a count was expected.
Common situations: Config schemas reusing a generic 'points' flag; LLM filling booleans into numeric slots; toggles accidentally bound to the wrong key.
Related errors
- T must be > 0 to imply a volatility, got {T}
- legs must be a non-empty array
- legs may contain at most {_MAX_LEGS} entries
- legs[{index}] must be an object
- legs[{index}] has invalid strike or qty: {exc}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b0616aba8a476650.
Report an issue: GitHub.