ZhuLinsen/daily_stock_analysis · warning · ValueError

unsupported alert_type for current EventMonitor runtime

Error message

unsupported alert_type for current EventMonitor runtime: {alert_type.value} (supported: {_supported_alert_type_names()})

What it means

_ensure_runtime_supported_alert_type guards AlertType values against _RUNTIME_SUPPORTED_ALERT_TYPES, a frozenset containing only PRICE_CROSS, PRICE_CHANGE_PERCENT and VOLUME_SPIKE. The AlertType enum defines more values (e.g. SENTIMENT_SHIFT at events.py:160), but the current EventMonitor runtime only implements checks for those three, so validating or evaluating any other alert type raises this ValueError naming the supported set.

Solutions

  1. Change the rule's alert_type to one of: price_change_percent, price_cross, volume_spike
  2. If you need sentiment alerts, implement the evaluation branch in EventMonitor and add the value to _RUNTIME_SUPPORTED_ALERT_TYPES
  3. Filter unsupported types out at load time and log, if you prefer degrade-over-fail for stored rules
  4. Keep the enum and the runtime frozenset in sync when adding new alert types

Example fix

// before
rule = {"stock_code": "600519", "alert_type": "sentiment_shift"}
validate_event_alert_rule(rule)  # ValueError

// after
rule = {"stock_code": "600519", "alert_type": "price_change_percent", "change_pct": 5, "direction": "up"}
validate_event_alert_rule(rule)
Defensive patterns

Strategy: validation

Validate before calling

from src.agent.events import _RUNTIME_SUPPORTED_ALERT_TYPES, AlertType

def alert_type_supported(value: str) -> bool:
    try:
        return AlertType(value) in _RUNTIME_SUPPORTED_ALERT_TYPES
    except ValueError:
        return False

Type guard

from src.agent.events import AlertType, _RUNTIME_SUPPORTED_ALERT_TYPES

def is_supported_alert_type(value: str) -> bool:
    try:
        return AlertType(value) in _RUNTIME_SUPPORTED_ALERT_TYPES
    except ValueError:
        return False

Prevention

When it happens

Trigger: validate_event_alert_rule() (events.py:473-ish) constructs AlertType(rule['alert_type']) then immediately calls this guard: submitting a rule with alert_type='sentiment_shift' (a legal enum member) raises. Also any code path that calls _ensure_runtime_supported_alert_type directly.

Common situations: Configs or API payloads written against the fuller enum surface; a rule store persisted with a sentiment rule from an earlier/other runtime; users enabling alert kinds the monitor's evaluation loop never checks.

Related errors


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

Appendix: source

Thrown at src/agent/events.py:68

    TRIGGERED = "triggered"
    EXPIRED = "expired"
    DISMISSED = "dismissed"


_RUNTIME_SUPPORTED_ALERT_TYPES = frozenset({
    AlertType.PRICE_CROSS,
    AlertType.PRICE_CHANGE_PERCENT,
    AlertType.VOLUME_SPIKE,
})


def _supported_alert_type_names() -> str:
    return ", ".join(sorted(alert_type.value for alert_type in _RUNTIME_SUPPORTED_ALERT_TYPES))


def _ensure_runtime_supported_alert_type(alert_type: AlertType) -> None:
    if alert_type not in _RUNTIME_SUPPORTED_ALERT_TYPES:
        raise ValueError(
            f"unsupported alert_type for current EventMonitor runtime: {alert_type.value} "
            f"(supported: {_supported_alert_type_names()})"
        )


def _read_quote_float(quote: Any, *field_names: str) -> Optional[float]:
    """Read a numeric field from quote objects or dict-like payloads."""
    if quote is None:
        return None

    for field_name in field_names:
        if isinstance(quote, dict):
            raw_value = quote.get(field_name)
        else:
            raw_value = getattr(quote, field_name, None)

        if raw_value is None and hasattr(quote, "to_dict"):
            try:

View on GitHub (pinned to 5159bd72e8)