HKUDS/Vibe-Trading · error · ValueError
spot_max must be greater than spot_min
Error message
spot_max must be greater than spot_min
What it means
Thrown by _spot_bounds when spot_max is not strictly greater than spot_min — equal bounds or inverted ranges produce an empty/invalid price grid. Both explicit values and pathological leg/strike combinations feeding defaults can surface here.
Source
Thrown at agent/src/tools/options_payoff_tool.py:313
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)
spot_max = _optional_float(kwargs, "spot_max", default_max)
if spot_min < 0:
raise ValueError("spot_min must be non-negative")
if spot_max <= spot_min:
raise ValueError("spot_max must be greater than spot_min")
return spot_min, spot_max
def _scenario_ivs(raw: Any, entry_iv: float) -> np.ndarray:
"""Resolve bounded explicit IV scenarios or the skill's five defaults."""
if raw is None:
values = [
entry_iv * 0.5,
entry_iv * 0.75,
entry_iv,
entry_iv * 1.25,
entry_iv * 1.5,
]
else:
if not isinstance(raw, list) or not raw:
raise ValueError("scenario_iv_values must be a non-empty array")
if len(raw) > _MAX_IV_SCENARIOS:
raise ValueError(f"scenario_iv_values may contain at most {_MAX_IV_SCENARIOS} entries")View on GitHub (pinned to 80ffdda44c)
Solutions
- Ensure spot_max > spot_min (add an epsilon or sanity margin)
- Derive bounds from data: spot_min=0.9*min_ref, spot_max=1.1*max_ref, then validate
- Omit both to use the tool's safe defaults
Example fix
// before
execute({..., "spot_min": 100, "spot_max": 100})
// after
execute({..., "spot_min": 90.0, "spot_max": 110.0}) Defensive patterns
Strategy: validation
Validate before calling
lo, hi = kwargs.get("spot_min"), kwargs.get("spot_max")
if lo is not None and hi is not None and float(hi) <= float(lo):
kwargs["spot_min"], kwargs["spot_max"] = None, None # use defaults Type guard
def bounds_ordered(lo, hi) -> bool:
return lo is None or hi is None or float(hi) > float(lo) Try / catch
try:
execute(kwargs)
except ValueError as e:
if "greater than spot_min" in str(e):
kwargs.update(spot_min=None, spot_max=None); execute(kwargs) Prevention
- Validate min<max in the form before submission
- Derive bounds from data with a margin
- Add epsilon checks in generated bound logic
When it happens
Trigger: spot_min=100, spot_max=100; spot_min=120, spot_max=80; or computed defaults collapsing when all strikes equal entry_spot and multipliers yield equal bounds via bad overrides.
Common situations: Copy-paste errors duplicating one number into both fields; off-by-one rounding making min meet max; automated bound generation without an epsilon check.
Related errors
- spot_min must be non-negative
- 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
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/7cdc85cd3a35b5c6.
Report an issue: GitHub.