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
-
failureAlert.threadId (the primary ask) — mirror what delivery accepts. Same Telegram bot, same group, just a topic-id selector.
-
failureAlert.inherit_from_delivery: true syntactic sugar — common case is "send failures to the same topic as success." Avoid duplication in cron configs.
-
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
- Accept
threadId in the failureAlert config schema.
- Optionally: support
inherit_from_delivery: true as a one-line shortcut for the common case.
- 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.
Environment
cliBackends.claude-cliTL;DR
A cron's
deliveryblock acceptsthreadIdto route a successful run's announcement to a specific Telegram topic. The companionfailureAlertblock does not — onlychannel,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-monitorjob 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:
Each cron's
deliverycorrectly routes to its topic. Each cron'sfailureAlertcannot route to its topic. The current fix at the workspace level is to run a dailycron-health-monitoraggregator that posts to the Ops topic — but this:What would help
failureAlert.threadId(the primary ask) — mirror whatdeliveryaccepts. Same Telegram bot, same group, just a topic-id selector.failureAlert.inherit_from_delivery: truesyntactic sugar — common case is "send failures to the same topic as success." Avoid duplication in cron configs.Document the failure-alert envelope shape in the docs site. Currently
<https://docs.openclaw.ai/cli/cron>coversdeliverythoroughly butfailureAlertis treated as a smaller surface. Either schema (parallel todelivery) 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-pluginsphase. 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
threadIdin thefailureAlertconfig schema.inherit_from_delivery: trueas a one-line shortcut for the common case.cli/cronpage to enumerate the fullfailureAlertschema next todelivery.References
kit-morning-digest,kit-cohort-refresh-*).failureAlertsilent drop on runtime-plugins stall, filed today.