ZhuLinsen/daily_stock_analysis · error · ValueError

Event alert rule must be an object

Error message

Event alert rule must be an object

What it means

validate_event_alert_rule() is the per-rule validator run after list-level checks. Its first assertion is that the rule is a dict; given Python's dynamic calls, passing a JSON-decoded scalar, an ORM object, or None raises ValueError('Event alert rule must be an object'). Unlike [238] this is the single-rule entry point, so callers looping over untrusted data hit it per item.

Source

Thrown at src/agent/events.py:466

        parsed = parsed.get("rules", [])

    if not isinstance(parsed, list):
        raise ValueError("Event alert rules must be a JSON array")

    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

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Convert the input to a plain dict before validating (dataclasses.asdict, model_dump, json round-trip)
  2. Type-check at the API boundary and return 400 for non-object bodies
  3. If looping over user data, pre-filter with isinstance(entry, dict) as [238]'s parser does
  4. Keep one normalization function so all callers pass the same shape

Example fix

// before
validate_event_alert_rule(request.args.get("rule"))  # str -> ValueError

// after
import json
rule = json.loads(request.get_data())
if not isinstance(rule, dict):
    abort(400, "rule must be a JSON object")
validate_event_alert_rule(rule)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(rule, dict):
    raise ValueError("rule must be a JSON object")

Type guard

def is_rule_object(rule) -> bool:
    return isinstance(rule, dict)

Prevention

When it happens

Trigger: Calling validate_event_alert_rule(rule) directly with a non-dict: a string from a form field, a list from a mis-parsed payload, None defaults, or a dataclass not converted via asdict().

Common situations: API handlers validating one request body that arrived as a JSON scalar; tests passing dataclasses; config loaders feeding raw TOML/JSON scalars.

Related errors


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