Summary
Isolated cron jobs configured with explicit Telegram announce delivery can be recorded as delivered: true / deliveryStatus: delivered in cron run history even when no Telegram message is actually sent to the user.
This makes scheduled follow-ups look successful internally while the user receives nothing.
Repro
Environment:
- OpenClaw
2026.3.8
- Telegram channel configured and working for normal direct replies in the same chat
Example cron job:
openclaw cron add \
--name "Test Telegram cron delivery" \
--at "2m" \
--session isolated \
--message "CRON_PROBE unique marker" \
--announce \
--channel telegram \
--to "208061542" \
--wake now \
--delete-after-run \
--json
Observed behavior:
- scheduler fires on time
- cron run finishes with
status: ok
openclaw cron runs --id <job-id> reports:
delivered: true
deliveryStatus: delivered
- but the Telegram user receives no message
- and gateway logs do not show the expected outbound log line like:
telegram sendMessage ok chat=208061542 message=...
Expected
delivered: true / deliveryStatus: delivered should only be recorded when the outbound message was actually delivered (or at minimum when the lower delivery layer confirms it).
If the message was not sent, the cron run should report something like:
delivered: false
deliveryStatus: not-delivered
- optionally with an error/reason
Likely cause
The problem appears to be in the shared subagent/cron announce completion path.
In the built artifact:
dist/pi-embedded-jHMb7qEG.js
- around
sendSubagentAnnounceDirectly(...)
that function does:
callGateway({ method: "agent", ..., deliver: true, channel, to, ... })
- if no exception is thrown, it returns:
{ delivered: true, path: "direct" }
That means the cron/subagent announce path seems to treat a successful agent call as a successful external delivery, without verifying actual outbound send success.
Relevant spots:
sendSubagentAnnounceDirectly(...) around lines ~12154-12204 in dist/pi-embedded-jHMb7qEG.js
runSubagentAnnounceDispatch(...) maps that directly into the final delivery result
- cron run history then records that as
delivered
By contrast, Telegram’s lower delivery path appears to track actual delivery using a real delivered flag (progress.hasDelivered) and logs telegram sendMessage ok ... on success.
Why this matters
This breaks trust in timed reminders/follow-ups:
- cron says delivery succeeded
- user gets nothing
- automation appears healthy when it is not
Suggested fix direction
One of these probably needs to happen:
callGateway(method: "agent") should return actual outbound delivery status when deliver: true
sendSubagentAnnounceDirectly() should not return delivered: true unless that lower-layer delivery is confirmed
- cron run accounting should distinguish:
- agent turn completed
- external message actually delivered
Notes
This was reproduced after an earlier separate issue where --session main --system-event cron jobs could be skipped with reason: no-target; this report is about the next layer deeper: even with isolated + announce + channel + to, delivery can still be recorded as successful without a real Telegram send.
Summary
Isolated cron jobs configured with explicit Telegram announce delivery can be recorded as
delivered: true/deliveryStatus: deliveredin cron run history even when no Telegram message is actually sent to the user.This makes scheduled follow-ups look successful internally while the user receives nothing.
Repro
Environment:
2026.3.8Example cron job:
Observed behavior:
status: okopenclaw cron runs --id <job-id>reports:delivered: truedeliveryStatus: deliveredtelegram sendMessage ok chat=208061542 message=...Expected
delivered: true/deliveryStatus: deliveredshould only be recorded when the outbound message was actually delivered (or at minimum when the lower delivery layer confirms it).If the message was not sent, the cron run should report something like:
delivered: falsedeliveryStatus: not-deliveredLikely cause
The problem appears to be in the shared subagent/cron announce completion path.
In the built artifact:
dist/pi-embedded-jHMb7qEG.jssendSubagentAnnounceDirectly(...)that function does:
callGateway({ method: "agent", ..., deliver: true, channel, to, ... })That means the cron/subagent announce path seems to treat a successful agent call as a successful external delivery, without verifying actual outbound send success.
Relevant spots:
sendSubagentAnnounceDirectly(...)around lines ~12154-12204 indist/pi-embedded-jHMb7qEG.jsrunSubagentAnnounceDispatch(...)maps that directly into the final delivery resultdeliveredBy contrast, Telegram’s lower delivery path appears to track actual delivery using a real delivered flag (
progress.hasDelivered) and logstelegram sendMessage ok ...on success.Why this matters
This breaks trust in timed reminders/follow-ups:
Suggested fix direction
One of these probably needs to happen:
callGateway(method: "agent")should return actual outbound delivery status whendeliver: truesendSubagentAnnounceDirectly()should not returndelivered: trueunless that lower-layer delivery is confirmedNotes
This was reproduced after an earlier separate issue where
--session main --system-eventcron jobs could be skipped withreason: no-target; this report is about the next layer deeper: even withisolated + announce + channel + to, delivery can still be recorded as successful without a real Telegram send.