#Difficulty Scheduling CRON jobs using openclaw

1 messages · Page 1 of 1 (latest)

young arrow
#

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.

coarse pebbleBOT
#

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:

  1. the model never actually created a cron job
  2. 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 list is 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 skipped with reasons like quiet-hours, empty-heartbeat-file, or no-tasks-due
    → the reminder may have been scheduled as a main-session wake, but heartbeat didn’t actually deliver it

  • auth / delivery errors like Forbidden or 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.

young arrow
#

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

coarse pebbleBOT
#

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 list shows a new pending request each time, use the newest requestId. The docs say old pending ids get superseded.
  • If devices list shows the device is already paired, but cron commands still fail, this may be a scope upgrade issue, commonly missing operator.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:

  1. run a failing cron command once
  2. run openclaw devices list
#
  1. approve the pending request
  2. 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:

If you paste the output of openclaw devices list, I can tell you exactly which entry to approve.

young arrow
#

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!

coarse pebbleBOT
#

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:

  1. one-shot at jobs auto-delete after success
  2. 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 runs will probably show it ran
  • heartbeat last may 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"
      }
#

If you paste the output of cron runs + system heartbeat last, I can tell you which of those two happened.

young arrow
#

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:~$

coarse pebbleBOT
#

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:

  1. cron fired successfully
  2. it was a main-session reminder, not a direct announce
  3. heartbeat was supposed to surface it
#
  1. heartbeat got skipped because your HEARTBEAT.md is empty
  2. 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:

  1. remove the blank HEARTBEAT.md, or put actual content in it
  2. 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:

If you want, I can help you write the exact openclaw.json snippet for either: