HKUDS/Vibe-Trading · error · ValueError
scenario_iv_values must contain numbers
Error message
scenario_iv_values must contain numbers
What it means
The options payoff tool validates the scenario_iv_values argument in _scenario_ivs. After confirming the input is a non-empty array of at most _MAX_IV_SCENARIOS entries, it attempts to coerce every element to float; if any element cannot be converted (string like 'abc', None, nested list, dict), the resulting TypeError/ValueError/OverflowError is re-raised as ValueError('scenario_iv_values must contain numbers').
Source
Thrown at agent/src/tools/options_payoff_tool.py:335
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")
try:
values = [float(value) for value in raw]
except (TypeError, ValueError, OverflowError) as exc:
raise ValueError("scenario_iv_values must contain numbers") from exc
array = np.asarray(values, dtype=float)
if not np.isfinite(array).all() or (array <= 0).any():
raise ValueError("scenario_iv_values must contain positive finite values")
return array
def _rounded(value: float) -> float:
"""Round a finite scalar for stable, compact JSON."""
return round(float(value), 6)
def _rounded_array(values: np.ndarray) -> list[float]:
"""Round a numeric array for stable, compact JSON."""
return [round(float(value), 6) for value in np.asarray(values).tolist()]
def _error(message: str) -> str:
"""Build a stable error envelope."""View on GitHub (pinned to 80ffdda44c)
Solutions
- Ensure every element is a number (int/float) in JSON, e.g. [0.2, 0.25, 0.3]
- Strip '%' and convert percent strings to decimals before calling
- Validate elements with isinstance(x,(int,float)) before invoking the tool
Example fix
// before tool.execute(scenario_iv_values=["20%", 0.25]) // after tool.execute(scenario_iv_values=[0.20, 0.25])
Defensive patterns
Strategy: validation
Validate before calling
ivs = kwargs.get("scenario_iv_values") or []
if not all(isinstance(v, (int, float)) and not isinstance(v, bool) for v in ivs):
ivs = [float(str(v).rstrip('%')) / 100 if isinstance(v, str) else v for v in ivs]
kwargs["scenario_iv_values"] = [float(v) for v in ivs] Type guard
def is_numeric_list(v: object) -> bool:
return isinstance(v, list) and bool(v) and all(
isinstance(x, (int, float)) and not isinstance(x, bool) for x in v
) Try / catch
try:
result = tool.execute(**kwargs)
except ValueError as e:
if "must contain numbers" in str(e):
kwargs["scenario_iv_values"] = sanitized(ivs); retry() Prevention
- Send JSON numbers, never quoted numerics
- Sanitize LLM output through a float() coercion layer
- Reject bools explicitly if strictness matters
When it happens
Trigger: Calling the options payoff tool's execute with scenario_iv_values=[0.2, 'high'] or [None, 0.3] or nested arrays. Booleans are accepted (float(True)==1.0); non-numeric strings and None are rejected.
Common situations: LLM-generated tool arguments with quoted vols ('20%'), passing a JSON object instead of an array, or None sentinels from upstream config defaults.
Related errors
- scenario_iv_values must contain positive finite values
- invalid period: {exc}
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/20045d34c6d0f11d.
Report an issue: GitHub.