ZhuLinsen/daily_stock_analysis · error · ValueError
{field_name} must be between {minimum} and {maximum}
Error message
{field_name} must be between {minimum} and {maximum} What it means
Raised by _int_in_range (src/services/alert_indicators.py:384) when an integer field parses fine but falls outside the inclusive range [minimum, maximum], which defaults to [2, 250] and applies to window, period, fast/slow/signal/k/d periods. Period-1 indicators need at least 2 points; 250 caps single-field history demand (see also error 327 for the summed-bars cap of 365).
Source
Thrown at src/services/alert_indicators.py:384
def _direction(value: Any, allowed: frozenset[str], *, default: str) -> str:
direction = str(value or default).strip().lower()
if direction not in allowed:
raise ValueError(f"invalid direction: {direction}")
return direction
def _int_in_range(value: Any, field_name: str, *, default: int, minimum: int = 2, maximum: int = 250) -> int:
raw_value = default if value is None or value == "" else value
try:
number = int(raw_value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid {field_name}: {value}") from exc
if str(raw_value).strip() not in {str(number), f"{number}.0"}:
raise ValueError(f"{field_name} must be an integer")
if number < minimum or number > maximum:
raise ValueError(f"{field_name} must be between {minimum} and {maximum}")
return number
def _finite_float(value: Any, field_name: str) -> float:
try:
number = float(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid {field_name}: {value}") from exc
if not isfinite(number):
raise ValueError(f"{field_name} must be finite")
return number
def _float_in_range(
value: Any,
field_name: str,
*,
minimum: float,View on GitHub (pinned to 5159bd72e8)
Solutions
- Clamp each integer field to 2..250 (e.g. window=200 is fine, window=300 is not).
- If you need >250-day windows, that single field cannot express it; reconsider the indicator or raise the cap in code after verifying data availability.
- Validate client-side with min=2 max=250 inputs.
Example fix
// before
{ "alert_type": "ma_price_cross", "parameters": { "window": 300 } }
// after
{ "alert_type": "ma_price_cross", "parameters": { "window": 250 } } Defensive patterns
Strategy: validation
Validate before calling
for k, v in params.items():
if k in INT_FIELDS:
n = int(v)
if not (2 <= n <= 250):
raise ValueError(f'{k} must be within 2..250; adjust the strategy instead of inflating periods') Type guard
def is_int_in_2_250(v) -> bool:
try:
return 2 <= int(v) <= 250
except (TypeError, ValueError):
return False Try / catch
try:
normalize_indicator_parameters(alert_type, params)
except ValueError as e:
if 'must be between 2 and 250' in str(e):
params.update({k: min(250, max(2, int(v))) for k, v in params.items() if k in INT_FIELDS})
normalize_indicator_parameters(alert_type, params)
else:
raise Prevention
- Set min=2, max=250 on every period input in the UI.
- Do not port period=1 tricks or 300-day windows from other platforms; redesign the alert instead.
- Prefer defaults (9/12/14/20/26) unless backtests justify long windows.
When it happens
Trigger: parameters like {"window": 1} or {"window": 0} (below minimum 2); {"period": 300} or {"period": 365} (above maximum 250). Note each individual field maxes at 250 even though the summed-bars check separately allows sums up to 365.
Common situations: Copy-pasting settings from another platform allowing period=1 (some RSI(1) tricks) or 300-day windows; template configs tuned for intraday bars reused on daily bars; 'more is smoother' period inflation.
Related errors
- invalid {field_name}: {value}
- {field_name} must be an integer
- {field_name} must be between {minimum:g} and {maximum:g}
- unsupported alert_type for current EventMonitor runtime: {al
- Event alert rules must be a JSON array
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/fe0150c160938758.
Report an issue: GitHub.