ZhuLinsen/daily_stock_analysis · error · ValueError

Event alert rules list must contain only objects; invalid en

Error message

Event alert rules list must contain only objects; invalid entries at positions: {invalid_indices}

What it means

After the rules payload is confirmed to be a list ([237]), the parser checks every element with isinstance(entry, dict). Any non-object element (string, number, nested array, null, bool) makes it raise ValueError listing the exact zero-based positions of the invalid entries, so users can locate the offenders without guessing.

Source

Thrown at src/agent/events.py:455

    if raw_rules is None:
        return []

    parsed = raw_rules
    if isinstance(raw_rules, str):
        cleaned = raw_rules.strip()
        if not cleaned:
            return []
        parsed = json.loads(cleaned)

    if isinstance(parsed, dict):
        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", ""))

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Remove or replace the scalar entries at the reported positions with full rule objects
  2. If the client meant to send identifiers, resolve them to full rules server-side first
  3. Map over the array at the producer to enforce object-ness before submit
  4. Return the error message verbatim to the client — the positions are actionable

Example fix

// before
[{"stock_code": "600519"}, "AAPL", null]

// after
[{"stock_code": "600519"}, {"stock_code": "AAPL", "alert_type": "price_cross", "price": 200}]
Defensive patterns

Strategy: validation

Validate before calling

invalid = [i for i, e in enumerate(rules) if not isinstance(e, dict)]
if invalid:
    raise ValueError(f"non-object rule entries at {invalid}")

Type guard

def all_rules_are_objects(rules: list) -> bool:
    return all(isinstance(e, dict) for e in rules)

Prevention

When it happens

Trigger: A rules array like ["alert", 42, null, {...}] — mixing raw values with rule objects; commonly from JSON where a rule was replaced by its ID, a name, or omitted fields collapsed to a scalar.

Common situations: Frontends sending [{id: 1}, {id: 2}] references instead of full rule objects; LLM-generated rule JSON emitting strings; copy-paste of stock codes directly into the array.

Related errors


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