ZhuLinsen/daily_stock_analysis · error · ValueError

invalid alert_type: {rule.get('alert_type')}

Error message

invalid alert_type: {rule.get('alert_type')}

What it means

Raised when rule['alert_type'] cannot be mapped to the AlertType enum (valid values: price_cross, price_change_percent, volume_spike, sentiment_shift, risk_flag, custom). The constructor AlertType(rule.get('alert_type', '')) raises ValueError, which is re-wrapped with the offending value in the message. Note that even a valid enum name like PRICE_CROSS fails here because AlertType is a str-Enum constructed from values, not names.

Source

Thrown at src/agent/events.py:475

            f"invalid entries at positions: {invalid_indices}"
        )

    return parsed


def validate_event_alert_rule(rule: Dict[str, Any]) -> None:
    """Validate one serialized EventMonitor rule."""
    if not isinstance(rule, dict):
        raise ValueError("Event alert rule must be an object")

    stock_code = str(rule.get("stock_code") or "").strip()
    if not stock_code:
        raise ValueError("stock_code is required")

    try:
        alert_type = AlertType(rule.get("alert_type", ""))
    except ValueError as exc:
        raise ValueError(f"invalid alert_type: {rule.get('alert_type')}") from exc
    _ensure_runtime_supported_alert_type(alert_type)

    status = rule.get("status")
    if status is not None:
        try:
            AlertStatus(status)
        except ValueError as exc:
            raise ValueError(f"invalid status: {status}") from exc

    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")

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Set alert_type to one of the exact enum values: 'price_cross', 'price_change_percent', 'volume_spike', 'sentiment_shift', 'risk_flag', 'custom'.
  2. Check stored/persisted rules for stale or renamed type strings and migrate them.
  3. If the value came from an LLM, constrain generation with an enum list in the prompt or validate against AlertType before persisting.

Example fix

// before
rule = {"stock_code": "AAPL", "alert_type": "PRICE_CROSS", "price": 200}
# ValueError: invalid alert_type: PRICE_CROSS

// after
rule = {"stock_code": "AAPL", "alert_type": "price_cross", "price": 200}
validate_event_alert_rule(rule)
Defensive patterns

Strategy: validation

Validate before calling

from src.agent.events import AlertType

def normalize_alert_type(raw) -> str | None:
    try:
        return AlertType(str(raw).strip().lower()).value
    except ValueError:
        return None

# before validating:
# if normalize_alert_type(rule.get("alert_type")) is None: reject

Type guard

def is_supported_alert_type(raw: object) -> bool:
    return normalize_alert_type(raw) is not None

Try / catch

try:
    validate_event_alert_rule(rule)
except ValueError as e:
    if str(e).startswith("invalid alert_type"):
        rule["alert_type"] = repair_or_default_type(rule)  # or reject
    else:
        raise

Prevention

When it happens

Trigger: validate_event_alert_rule with alert_type missing (defaults to ''), misspelled ('price-cross', 'pricecross'), uppercase enum name ('PRICE_CROSS'), or any string outside the six enum values. Also triggered by non-string values like None or 1.

Common situations: Hand-written rule JSON copied from docs that use the enum member name instead of the snake_case value; LLM-generated rules inventing type names; schema drift after a new AlertType was added but stored rules use an old/newer vocabulary; frontend dropdown using labels instead of values.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/289ae0615d45922c. Report an issue: GitHub.