I have just recently installed openclaw, and am having diffuclty scheduling CRON jobs. I ask openclaw to 'please send me a reminder message in 10 mins to check in on my work' and then it says that it will do that, but doesn't send anything. I am new to openclaw, and this is one of the first things that I am trying to do. I have set up openclaw so I am talking to it in my discord and it can reply to me and acess my computers files. I am using a free cloud model from ollama, minmax 2.7. How can I debug this so that I can ask it to send me reminders about things at certain times.
#Difficulty Scheduling CRON jobs using openclaw
1 messages · Page 1 of 1 (latest)
Let me check the docs paths and the cron/reminder docs so I can give you the right debugging steps.
I found the cron docs. I’m pulling the FAQ and the automation troubleshooting page too, since those usually have the gotchas for “it said it would remind me, but nothing arrived.”
You’re usually debugging one of 2 things here:
- the model never actually created a cron job
- the cron job ran, but delivery failed
The fastest debug loop is:
openclaw --version
openclaw status
openclaw cron status
openclaw cron list
openclaw system heartbeat last
openclaw logs --follow
What to look for:
-
cron listis empty right after you asked for the reminder
→ the model said “I’ll do that” but never made the cron tool call -
cron: scheduler disabled; jobs will not run automatically
→ cron is disabled -
Gateway is not continuously running, or your laptop slept/restarted
→ scheduled jobs won’t fire -
heartbeat skippedwith reasons likequiet-hours,empty-heartbeat-file, orno-tasks-due
→ the reminder may have been scheduled as a main-session wake, but heartbeat didn’t actually deliver it -
auth / delivery errors like
Forbiddenor missing target
→ the job ran, but sending the message failed
If cron list shows a job, grab the job id and run:
openclaw cron runs --id <jobId> --limit 20
openclaw tasks list --runtime cron
That will tell you whether the run was ok, skipped, or error.
One important gotcha: heartbeat delivery defaults to target: "none".
So if your reminder is being routed through heartbeat, set:
{
agents: {
defaults: {
heartbeat: {
target: "last"
}
}
}
}
then restart the gateway:
openclaw gateway restart
Also, the cleanest isolation test is to create one reminder via CLI, so the model is out of the loop:
openclaw cron add \
--name "debug reminder" \
--at "10m" \
--session main \
--system-event "Reminder: check in on your work." \
--wake now
If that works, cron is fine and the issue is the natural-language tool-use path.
If that does not work, it’s scheduler/delivery config.
Docs:
If you paste the outputs of the first 5 commands, I can help narrow it down pretty quickly.
System Environment
OpenClaw Version: 2026.4.8 (9ece252)
OS: Linux 6.8.0-107-generic (x64)
Node: 22.22.2
Target: ws://127.0.0.1:18789 (Local loopback)
Config: /home/horatio/.openclaw/openclaw.json
The Error
When running cron status, cron list, or system heartbeat last, the CLI returns:
Error: gateway closed (1008): pairing required
GatewayClientRequestError: pairing required
Current Status (Overview)
Gateway Service: Installed, enabled, and running (PID 4569, state active).
Discord Channel: ON (OK).
Sessions: 2 active (minimax-m2.5:cloud and gemma4:e4b).
Update: Available (npm 2026.4.14).
Security Audit Highlights
1 Critical: Small model (gemma4:e4b) detected without sandboxing.
Warnings: * gateway.controlUi.allowInsecureAuth=true is enabled.
Reverse proxy headers are not trusted (loopback bind, empty trustedProxies).
Multi-user setup detected via
I’ve seen that 1008: pairing required path before. Let me verify the exact docs wording so I don’t send you on a goose chase.
Nice, this narrows it down a lot.
This is not a cron bug yet. Your CLI is getting blocked by gateway pairing, so cron status, cron list, and system heartbeat last never actually reach the scheduler.
What I’d do next:
openclaw devices list
Important: run it without an explicit --url. On local loopback, devices list can fall back to local pairing files even when normal gateway calls are hitting pairing required.
If you see a pending request, approve it with the exact id:
openclaw devices approve <requestId>
Then retry:
openclaw cron status
openclaw cron list
openclaw system heartbeat last
A couple of useful notes here:
- If
devices listshows a new pending request each time, use the newestrequestId. The docs say old pending ids get superseded. - If
devices listshows the device is already paired, but cron commands still fail, this may be a scope upgrade issue, commonly missingoperator.write. In that case, the pending request will usually show the requested scopes, or you can rotate the device token later if needed.
So the likely flow is:
- run a failing cron command once
- run
openclaw devices list
- approve the pending request
- rerun cron commands
Also, you’re on 2026.4.8 and the CLI says 2026.4.14 is available. I’d fix pairing first, then update, because there have been a lot of small device/auth/automation fixes lately.
The other warnings you pasted, like allowInsecureAuth=true and the small-model sandbox warning, are worth cleaning up, but they are not the thing blocking cron right now.
Docs:
- https://docs.openclaw.ai/cli/devices
- https://docs.openclaw.ai/gateway/troubleshooting#dashboard-control-ui-connectivity
- https://docs.openclaw.ai/help/faq#the-control-ui-says-unauthorized-or-keeps-reconnecting-what-now
If you paste the output of openclaw devices list, I can tell you exactly which entry to approve.
okay, nice I paired the device and things seemed to be working.
Me: Can you schedule a CRON job to send me a message saying hi in 2.5 mins?
openclaw: Done! Scheduled a one-shot cron to say "Hi!" at 8:29:30 PM (in ~2.5 mins). You'll see it pop into chat
when it fires.
connected | idle
agent main | session main (openclaw-tui) | ollama/minimax-m2.7:cloud | tokens 15k/197k (8%)
and then horatio@theseus:~$ openclaw cron list
🦞 OpenClaw 2026.4.14 (323493f)
If it's repetitive, I'll automate it; if it's hard, I'll bring jokes and a rollback plan.
│
â—‡
ID Name Schedule Next Last Status Target Agent ID Model
e6bf78db-2d51-446a-9625-78de4ec5900b Hi reminder at 2026-04-15 20:29Z in 1m - idle main main -
but then the cron job dispared when the time was reached and nothing happened!
Yep, this makes sense now.
The key clue is this column:
Target main
That means OpenClaw created a main-session cron, not a direct “announce to Discord” job.
Two important doc behaviors line up with what you saw:
- one-shot
atjobs auto-delete after success - heartbeat/default main-session delivery can run with no external message if no target resolves
So the cron disappearing is actually normal. The real issue is: it likely fired into the main TUI session, not back into Discord.
Since you created it from:
session main (openclaw-tui)
…I’d expect exactly this failure mode.
Check that theory
Run:
openclaw cron runs --id e6bf78db-2d51-446a-9625-78de4ec5900b --limit 20
openclaw system heartbeat last
What I expect:
cron runswill probably show it ranheartbeat lastmay show it ran but had no external delivery target, or was skipped
Best fix, recommended
For reminders that should definitely show up in Discord, use an isolated + announce cron, not target=main.
Example:
openclaw cron add \
--name "Hi reminder" \
--at "2.5m" \
--session isolated \
--message 'Send "Hi!"' \
--announce \
--channel discord \
--to "channel:<discord-channel-or-thread-id>"
That path is much more predictable for “message me at an exact time”.
Other fix
If you want to keep using main-session reminders, then heartbeat needs an external target, for example:
{
agents: {
defaults: {
heartbeat: {
target: "last"
}
}
}
}
But that works best when you ask from the Discord thread itself, not from openclaw-tui, because target: "last" uses the last external channel for that session.
So my recommendation is:
- ask from Discord if you want the reminder in Discord, or
- use isolated + announce for exact reminder delivery
Docs:
If you paste the output of cron runs + system heartbeat last, I can tell you which of those two happened.
I tried to send it from discord, but it didn't work!
els/discord"} logged in to discord as 1493492312251306014 (Sisyphus)
21:11:48+00:00 info cron {"module":"cron","storePath":"/home/horatio/.openclaw/cron/jobs.json"} {"jobId":"50e691f5-f76a-4725-a0ae-f431f6356d14","jobName":"Hello ping","nextRunAtMs":1776287597556,"schedulerNextWakeAtMs":1776287597556,"timerArmed":true,"cronEnabled":true} cron: job added
21:11:48+00:00 info gateway {"subsystem":"gateway"} {"jobId":"50e691f5-f76a-4725-a0ae-f431f6356d14","schedule":{"kind":"at","at":"2026-04-15T21:13:17.556Z"}} cron: job created
21:14:34+00:00 info No cron jobs.
21:20:13+00:00 info No cron jobs.
horatio@theseus:~$ openclaw cron runs --id 50e691f5-f76a-4725-a0ae-f431f6356d14 --limit 20
openclaw system heartbeat last
🦞 OpenClaw 2026.4.14 (323493f)
If it's repetitive, I'll automate it; if it's hard, I'll bring jokes and a rollback plan.
│
â—‡
{
"entries": [
{
"ts": 1776287635789,
"jobId": "50e691f5-f76a-4725-a0ae-f431f6356d14",
"action": "finished",
"status": "ok",
"summary": "Hello from cron! 🪨",
"runAtMs": 1776287597560,
"durationMs": 38227,
"nextRunAtMs": 1776287597556,
"deliveryStatus": "not-requested"
}
],
"total": 1,
"offset": 0,
"limit": 20,
"hasMore": false,
"nextOffset": null
}
🦞 OpenClaw 2026.4.14 (323493f)
I've survived more breaking changes than your last three relationships.
│
â—‡
{
"ts": 1776288087518,
"status": "skipped",
"reason": "empty-heartbeat-file",
"durationMs": 1
}
horatio@theseus:~$
Nice, we found it.
Your cron job did run successfully:
status: "ok"- summary:
"Hello from cron! 🪨"
The two smoking guns are:
deliveryStatus: "not-requested"- heartbeat last:
reason: "empty-heartbeat-file"
So the flow was:
- cron fired successfully
- it was a main-session reminder, not a direct announce
- heartbeat was supposed to surface it
- heartbeat got skipped because your
HEARTBEAT.mdis empty - nothing got sent
What to fix
Option 1, recommended
Use isolated + announce reminders for exact Discord messages.
That bypasses heartbeat entirely.
Example:
openclaw cron add \
--name "Hello ping" \
--at "2.5m" \
--session isolated \
--message 'Reply with exactly: Hello from cron!' \
--announce \
--channel discord \
--to "channel:<discord-thread-or-channel-id>"
This is the most reliable path for “send me a message at X time”.
Option 2
Keep main-session reminders, but fix heartbeat:
- remove the blank
HEARTBEAT.md, or put actual content in it - set heartbeat delivery target, for example:
{
agents: {
defaults: {
heartbeat: {
target: "last"
}
}
}
}
Then restart:
openclaw gateway restart
My recommendation
For reminders, I’d use isolated + announce.
For ongoing periodic “check stuff” behavior, use heartbeat.
Right now your setup is proving:
- cron scheduler: âś… working
- model/tool call: âś… working
- delivery path for this reminder shape: ❌ blocked by heartbeat config
Docs:
- https://docs.openclaw.ai/automation/cron-jobs
- https://docs.openclaw.ai/gateway/heartbeat
- https://docs.openclaw.ai/gateway/troubleshooting#cron-and-heartbeat-delivery
If you want, I can help you write the exact openclaw.json snippet for either: