-
-
Notifications
You must be signed in to change notification settings - Fork 52.6k
Description
Bug Description
One-shot cron jobs (schedule.kind: "at" + deleteAfterRun: true + sessionTarget: "main" + payload.kind: "systemEvent") fire repeatedly when the gateway restarts after the scheduled time has passed.
The jobs get lastStatus: "skipped" (likely because the main session is busy), which does not count as a successful run, so deleteAfterRun never triggers. On each subsequent gateway restart, the overdue job is re-evaluated and re-injected, causing dozens of duplicate systemEvents.
Environment
- OpenClaw Version: 2026.2.6-3
- OS: macOS 15.7.3 (ARM64)
- Node: v22.22.0
- Channel: Telegram
Steps to Reproduce
- Create a one-shot reminder:
{
"schedule": { "kind": "at", "at": "2026-02-10T22:30:00.000Z" },
"payload": { "kind": "systemEvent", "text": "⏰ Reminder: Time to workout!" },
"sessionTarget": "main",
"deleteAfterRun": true
}-
Let the scheduled time pass while the main session is active (chatting with user)
-
The systemEvent fires but gets
lastStatus: "skipped" -
Restart the gateway (e.g., via
config.patchoropenclaw gateway restart) -
Observe: The same reminder fires again. Repeat step 4 → fires again each time.
In our case, multiple config changes triggered ~10 gateway restarts in an evening, resulting in 20+ duplicate reminder messages flooding the session.
Expected Behavior
- Overdue
atjobs withdeleteAfterRun: trueshould be deleted (or at minimum disabled) after the scheduled time passes, regardless of whether the delivery was "skipped" - A
systemEventinjection should not be skippable — it is a fire-and-forget text injection, not an agent turn that can fail
Actual Behavior
- The job stays alive with
lastStatus: "skipped"anddeleteAfterRunnever fires - Each gateway restart re-injects the systemEvent, causing duplicates
- The only fix is manually removing the job via
cron remove
Cron Job State After Bug
{
"lastStatus": "skipped",
"lastDurationMs": 0,
"runningAtMs": 1770774567831
}Workaround
Use sessionTarget: "isolated" + payload.kind: "agentTurn" instead of main + systemEvent for one-shot reminders. Isolated jobs complete independently and trigger deleteAfterRun correctly.
Related
- [Bug] Telegram bot stuck in infinite loop sending duplicate messages - session state persists across restarts #5806 (session state persists across restarts causing infinite loops)
- Herbert Yang's report on orphaned
.tmpfiles in cron recovery logic