ZhuLinsen/daily_stock_analysis · error · ValueError

stock_code is required

Error message

stock_code is required

What it means

Raised by validate_event_alert_rule in src/agent/events.py when a serialized EventMonitor rule dict has a missing, empty, or whitespace-only 'stock_code' field. stock_code is the mandatory identity key that ties an alert rule to the instrument it monitors, so an empty value makes the rule unusable. This is a pure input-validation error at the rule-parsing boundary, not a runtime market-data failure.

Source

Thrown at src/agent/events.py:470

    invalid_indices = [idx for idx, entry in enumerate(parsed) if not isinstance(entry, dict)]
    if invalid_indices:
        raise ValueError(
            "Event alert rules list must contain only objects; "
            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)

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Ensure the rule dict contains a non-empty 'stock_code' string (e.g. '600519', 'hk00700', 'AAPL') before validation.
  2. If rules come from an LLM or user input, add a schema check (presence + non-blank) at the ingestion boundary and reject/repair early with a clearer message.
  3. If a default instrument is intended, populate stock_code explicitly from context instead of relying on an optional field.

Example fix

// before
rule = {"alert_type": "price_cross", "price": 100}
validate_event_alert_rule(rule)  # ValueError: stock_code is required

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

Strategy: validation

Validate before calling

def has_stock_code(rule: dict) -> bool:
    return bool(str(rule.get("stock_code") or "").strip())

Type guard

def is_valid_rule_shell(rule: object) -> bool:
    return isinstance(rule, dict) and has_stock_code(rule)

Try / catch

try:
    validate_event_alert_rule(rule)
except ValueError as e:
    logger.warning("rejected alert rule: %s", e)
    # drop or send back for repair; do not add to EventMonitor

Prevention

When it happens

Trigger: Calling validate_event_alert_rule(rule) (directly or via any API that deserializes persisted/LLM-generated alert rules, e.g. adding rules to EventMonitor) with a dict where rule['stock_code'] is absent, None, '', or ' '. Note str(rule.get("stock_code") or '') coerces non-strings, so 0 or empty containers also become '' and fail.

Common situations: Alert rules round-tripped from JSON storage where the key was dropped; LLM-generated rule payloads that omit the ticker; upstream code that stores quote-based rules keyed by name instead of code; a frontend form submitting the field before the user picks a stock.

Related errors


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