ZhuLinsen/daily_stock_analysis · error · ValueError
price must be > 0
Error message
price must be > 0
What it means
Raised for PRICE_CROSS rules when 'price' parses as a float but is <= 0. A zero or negative threshold is meaningless for a stock price cross, so validation rejects it before the rule can enter the monitor and never trigger (or always mis-trigger).
Source
Thrown at src/agent/events.py:503
ttl_hours = rule.get("ttl_hours")
if ttl_hours is not None:
try:
ttl_value = float(ttl_hours)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid ttl_hours: {ttl_hours}") from exc
if ttl_value <= 0:
raise ValueError("ttl_hours must be > 0")
if alert_type == AlertType.PRICE_CROSS:
direction = str(rule.get("direction", "above")).lower()
if direction not in {"above", "below"}:
raise ValueError(f"invalid direction: {direction}")
try:
price = float(rule.get("price"))
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid price: {rule.get('price')}") from exc
if price <= 0:
raise ValueError("price must be > 0")
elif alert_type == AlertType.PRICE_CHANGE_PERCENT:
direction = str(rule.get("direction", "up")).lower()
if direction not in {"up", "down"}:
raise ValueError(f"invalid direction: {direction}")
try:
change_pct = float(rule.get("change_pct"))
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid change_pct: {rule.get('change_pct')}") from exc
if change_pct <= 0:
raise ValueError("change_pct must be > 0")
elif alert_type == AlertType.VOLUME_SPIKE:
try:
multiplier = float(rule.get("multiplier", 2.0))
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid multiplier: {rule.get('multiplier')}") from exc
if multiplier <= 0:
raise ValueError("multiplier must be > 0")
View on GitHub (pinned to 5159bd72e8)
Solutions
- Set price to the positive absolute price threshold you want (e.g. 1800.0).
- If you meant a percentage move, use alert_type='price_change_percent' with change_pct instead of price.
- Validate extracted prices at the LLM-parsing layer: reject 0/negative placeholders and re-ask or fall back to the current quote.
Example fix
// before
rule = {"stock_code": "600519", "alert_type": "price_cross", "direction": "above", "price": 0}
# ValueError: price must be > 0
// after
rule = {"stock_code": "600519", "alert_type": "price_cross", "direction": "above", "price": 1800.0}
validate_event_alert_rule(rule) Defensive patterns
Strategy: validation
Validate before calling
def positive_price(raw) -> bool:
try:
return float(raw) > 0
except (TypeError, ValueError):
return False Type guard
def has_positive_price(rule: dict) -> bool:
return positive_price(rule.get("price")) Try / catch
try:
validate_event_alert_rule(rule)
except ValueError as e:
if "price must be" in str(e):
reject(rule, "price threshold must be a positive absolute price") Prevention
- Reject 0/negative LLM placeholder prices at extraction time.
- Use price_change_percent if a relative move was intended.
- Guard UI numeric inputs with min>0.
When it happens
Trigger: validate_event_alert_rule with alert_type='price_cross' and price = 0, -50, 0.0, or '0'. Also reachable when unparsed text coerces unexpectedly (e.g. float of a string like '0').
Common situations: Unset numeric UI field defaulting to 0; an LLM emitting 0 as a placeholder for 'current price'; negative values from buggy delta/threshold arithmetic being reused as absolute price; sentinel -1 reused from a different config schema.
Related errors
- ttl_hours must be > 0
- invalid price: {rule.get('price')}
- 配置校验失败
- unsupported alert_type for current EventMonitor runtime: {al
- stock_code is required
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/df9fedec79388f02.
Report an issue: GitHub.