Skip to content

[Enhancement]: failureAlert lacks threadId — per-cron failure alerts land in the wrong Telegram topic, forcing operators to watch an aggregate-only path #89848

Description

@BryceMurray

Environment

  • OpenClaw: 2026.5.28
  • Backend: cliBackends.claude-cli
  • Channel: Telegram (forum-mode supergroup with topics)
  • Related: <companion issue — failureAlert silent-drop on runtime-plugins stall> (the technical bug); this issue is about the observability shape when alerts do successfully fire.

TL;DR

A cron's delivery block accepts threadId to route a successful run's announcement to a specific Telegram topic. The companion failureAlert block does not — only channel, to, after, mode. As a result, per-cron failure alerts land in the chat's default thread rather than the topic the operator is watching for that cron's domain.

In a workspace with topic-organized Telegram channels (one topic per project/skill), operators end up needing to either (a) watch every topic for cross-topic failure noise, or (b) rely entirely on an aggregate cron-health-monitor job that delivers to yet another topic. Both fail the principle "alerts surface where the operator is already looking."

Symptom

Cron config (verified via openclaw cron get <id> — redacted):

{
  "delivery": {
    "mode": "announce",
    "channel": "telegram",
    "to": "<group-id>",
    "threadId": 79,           // ← routes the success-line to topic 79
    "bestEffort": true
  },
  "failureAlert": {
    "after": 1,
    "mode": "announce",
    "channel": "telegram",
    "to": "<group-id>"        // ← no threadId field accepted
  }
}

Result: on success, the cron posts "ok" to topic 79 (correct). On failure, the alert lands in the chat's default thread (or topic 0) — invisible to the operator monitoring topic 79.

Workspace context (why this matters at the org level)

A real workspace has ~46 crons across ~14 skill domains. Topic-organized chat:

  • topic 79 — Keep In Touch (KIT) skill
  • topic 65 — Ops (system-wide health digest)
  • topic — Gmail triage
  • topic — Real-estate intel
  • (etc.)

Each cron's delivery correctly routes to its topic. Each cron's failureAlert cannot route to its topic. The current fix at the workspace level is to run a daily cron-health-monitor aggregator that posts to the Ops topic — but this:

  • Delays failure visibility by up to 24h (depends on health-monitor's schedule)
  • Forces operators to watch a third topic in addition to the per-cron topics they care about
  • Loses the routing benefit of having topics in the first place

What would help

  1. failureAlert.threadId (the primary ask) — mirror what delivery accepts. Same Telegram bot, same group, just a topic-id selector.

  2. failureAlert.inherit_from_delivery: true syntactic sugar — common case is "send failures to the same topic as success." Avoid duplication in cron configs.

  3. Document the failure-alert envelope shape in the docs site. Currently <https://docs.openclaw.ai/cli/cron> covers delivery thoroughly but failureAlert is treated as a smaller surface. Either schema (parallel to delivery) or shape doc would close the gap.

Companion issue

This is paired with a separate bug — the failure-alert envelope silently fails to deliver at all when the cron stalls in the runtime-plugins phase. Fixing this enhancement ticket without fixing that bug doesn't help (alerts still don't reach the operator). Fixing this with the bug fix gives operators a reliable per-cron failure surface in the topic they're already monitoring.

Asks

  1. Accept threadId in the failureAlert config schema.
  2. Optionally: support inherit_from_delivery: true as a one-line shortcut for the common case.
  3. Update the docs site cli/cron page to enumerate the full failureAlert schema next to delivery.

References

  • Real cron showing the asymmetry: any KIT cron in the workspace (e.g. kit-morning-digest, kit-cohort-refresh-*).
  • Companion bug — failureAlert silent drop on runtime-plugins stall, filed today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions