OpenClaw Cron Jobs: Why They Break and How to Fix Them (2026 Guide)

Affiliate Disclosure: This post contains affiliate links. If you purchase through our links, we may earn a commission at no extra cost to you. We only recommend tools we've personally tested and believe in.

If you've landed here, you've probably already spent an embarrassing amount of time staring at an OpenClaw cron job that simply refuses to fire. You've double-checked the syntax. You've restarted things. You've watched the cursor blink. Nothing.

You're not alone. Search Reddit for “OpenClaw cron jobs” and you'll find threads that read like a support group: “What's the recommended way to set up cron jobs?” and the particularly brutal “Never works. I've had it use cron.add, had it edit JSON directly… It has said itself that it is out of ideas.”

That second one stings because the AI admitting defeat is about as demoralizing as it gets.

Here's the good news: OpenClaw cron jobs absolutely work. The problem isn't the feature — it's that there's almost no documentation covering the actual failure modes. This guide is the one I wish existed when I started. We'll cover every reason they break, with working copy-paste examples for the most common use cases.


Why OpenClaw Cron Jobs Feel So Confusing

Dark terminal screen showing automated cron job output running at midnight
OpenClaw cron jobs running automated tasks while you sleep — the terminal output at midnight.

Most automation tools give you one scheduling syntax. OpenClaw gives you three — plus two execution modes — and the interactions between them are where most people get lost.

Before we troubleshoot anything, let's establish a shared mental model.

The 3 schedule types:

  • --at — One-time execution at a specific time or offset
  • --every — Repeating interval (every N minutes/hours/days)
  • --cron — Standard Unix cron expression (5-field format)

The 2 execution modes:

  • Main session mode — Job runs inside your primary ongoing agent session
  • Isolated session mode — Job spawns a fresh, independent agent session to execute

The combination you choose has huge implications for reliability. Most beginners default to main session mode without realizing it, then wonder why jobs queue silently or never fire. We'll fix that.


The 3 Schedule Types, Explained with Real CLI Examples

–at: One-Time Tasks

Use --at when you need something to happen once — either at an absolute time or after a relative offset from now.

# Fire 30 minutes from now
openclaw cron add --at "30m" --name "quick-reminder" --announce \
  --prompt "Remind me to take a break and drink water."

# Fire at a specific UTC time
openclaw cron add --at "2026-03-20T09:00:00Z" --name "morning-brief" --announce \
  --prompt "Run my morning briefing: check email, weather, and calendar for today."

# Fire in 2 hours with auto-cleanup
openclaw cron add --at "2h" --name "meeting-prep" --announce --delete-after-run \
  --prompt "Summarize the agenda doc at ~/docs/meeting-agenda.md and send it to me."

The --delete-after-run flag is your friend for one-shot jobs. Without it, the job stays in your list as a completed artifact — not harmful, but noisy.

–every: Repeating Intervals

Use --every for regular recurring tasks where exact time-of-day doesn't matter — only the interval does.

# Check inbox every 6 hours
openclaw cron add --every "6h" --name "inbox-check" --announce --best-effort-deliver \
  --prompt "Check my email for anything urgent. Summarize unread messages from the last 6 hours."

# Quick status check every 30 minutes
openclaw cron add --every "30m" --name "status-ping" --announce \
  --prompt "Brief status check: anything I should know about?"

# Daily at interval (not time-locked — drifts with restarts)
openclaw cron add --every "24h" --name "daily-digest" --announce \
  --prompt "Generate my daily digest: key tasks, pending items, priorities."

Important caveat on --every: The interval starts from when the job was created or last ran — not from midnight. If you restart the gateway, the timer resets. For exact time-of-day scheduling, use --cron instead.

–cron: Standard Cron Expressions

Use --cron when you need precise scheduling — “every Monday at 9 AM”, “first of the month”, etc. This accepts standard 5-field Unix cron syntax.

# Every weekday at 9 AM UTC (minute hour day month weekday)
openclaw cron add --cron "0 9 * * 1-5" --name "weekday-brief" --announce \
  --prompt "Good morning briefing: summarize my calendar, priority emails, and top 3 tasks."

# Weekly report every Monday at 8 AM UTC
openclaw cron add --cron "0 8 * * 1" --name "weekly-report" --announce --best-effort-deliver \
  --prompt "Generate my weekly report. Summarize last week's completed tasks and set priorities for this week."

# Every 6 hours at exact times (midnight, 6am, noon, 6pm UTC)
openclaw cron add --cron "0 0,6,12,18 * * *" --name "inbox-check-exact" --announce \
  --prompt "Check email for urgent messages and summarize."

Remember: OpenClaw cron uses UTC. If you're in EST (UTC-5), “9 AM UTC” is 4 AM your time. Adjust accordingly — we'll cover this more in the failure modes section.


⏱️

–at

One-time execution at a specific time or offset from now.

Best for: Reminders, one-shot tasks, meeting prep

🔄

–every

Repeating interval. Timer starts from creation or last run.

Best for: Periodic checks where exact time doesn't matter

📅

–cron

Standard 5-field Unix cron expression. Exact time-of-day scheduling.

Best for: Daily briefings, weekly reports, exact schedules

Main Session vs. Isolated Session: Which Should You Use?

This is the single most important decision you'll make with OpenClaw cron jobs, and most guides don't even mention it.

Main session mode runs your cron job inside your existing primary agent session — the same one you're actively chatting in. This sounds convenient, but it has a critical problem: if that session is busy, sleeping, or has no active heartbeat, your job may queue silently and never execute on time. Or at all.

Isolated session mode spawns a fresh agent session specifically for the cron job, executes it, and tears down. It doesn't care what your main session is doing. It just runs.

Use isolated sessions for almost everything. Here's when each mode makes sense:

Use Main Session When… Use Isolated Session When…
You need access to main session memory/context Task is self-contained (most tasks)
You have heartbeat configured and running You want reliable, on-time execution
Low-frequency jobs with flexible timing Anything time-sensitive
You're not actively using OpenClaw when the job fires

To use isolated session mode, add the --isolated flag (check your version's CLI docs — the flag name may vary) or configure it in your job's JSON. When in doubt, isolated wins.


⚠️ Main Session Mode

  • Runs inside your active chat session
  • Queues silently if session is dormant
  • Needs heartbeat to stay alive
  • Use only when you need session memory

✅ Isolated Session Mode

  • Spawns a fresh session just for the job
  • Runs regardless of main session state
  • Executes on time, tears down after
  • Use for almost everything

Top 5 Reasons Your OpenClaw Cron Jobs Fail (And How to Fix Each One)

Failure #1: Job Created But Never Fires — Gateway Not Running

This is the most common and most frustrating failure. You create the job, confirm it was added, walk away, and nothing happens.

OpenClaw cron jobs only execute if the gateway daemon is running. If the daemon stopped (reboot, crash, manual stop), all your jobs are essentially paused — and when the daemon restarts, jobs don't automatically backfill missed executions.

Fix:

# Check gateway status
openclaw gateway status

# If not running, start it
openclaw gateway start

# Verify your jobs are still listed
openclaw cron list

For long-term reliability, configure the gateway as a system service that starts on boot. On Linux:

# Enable auto-start (systemd)
systemctl --user enable openclaw-gateway
systemctl --user start openclaw-gateway

Also check: after a gateway restart, run openclaw cron list immediately. If your jobs survived the restart, they'll be listed. If not, they may have been stored in-memory only and need to be recreated.

Failure #2: Wrong Timezone — OpenClaw Uses UTC

You set a cron job for “9:00 AM” and it fires at 2 AM. Or 4 PM. Or seemingly random times.

OpenClaw cron operates in UTC. Full stop. There's no automatic timezone conversion based on your system locale.

Fix: Always calculate your times in UTC. If you're in a timezone with DST, remember that your UTC offset changes twice a year.

# Quick UTC conversion cheat sheet (standard time):
# EST (UTC-5):  9 AM local = 14:00 UTC → cron: "0 14 * * *"
# CST (UTC-6):  9 AM local = 15:00 UTC → cron: "0 15 * * *"
# MST (UTC-7):  9 AM local = 16:00 UTC → cron: "0 16 * * *"
# PST (UTC-8):  9 AM local = 17:00 UTC → cron: "0 17 * * *"
# GMT (UTC+0):  9 AM local = 09:00 UTC → cron: "0 9 * * *"
# CET (UTC+1):  9 AM local = 08:00 UTC → cron: "0 8 * * *"

# Example: 9 AM EST daily briefing
openclaw cron add --cron "0 14 * * *" --name "morning-brief-est" --announce \
  --prompt "Run my morning briefing."

Failure #3: Main Session Mode + No Heartbeat = Silent Queue

You've configured cron jobs to run in main session mode. The gateway is running. UTC is correct. Jobs still don't fire.

When a cron job targets your main session, it needs that session to be “awake” — actively polling or receiving messages. If you haven't sent a message in hours, or if heartbeat isn't configured, the session may be in a dormant state. Your job gets queued but never processed.

Fix option 1: Switch to isolated session mode (recommended).

Fix option 2: If you must use main session, configure a heartbeat so the session stays active.

# Heartbeat every 30 minutes keeps main session alive
openclaw cron add --every "30m" --name "session-heartbeat" \
  --prompt "Heartbeat check. Read HEARTBEAT.md and act on anything pending. Reply HEARTBEAT_OK if nothing to do."

The more robust solution is always isolated mode. The heartbeat approach is a bandage.

Failure #4: JSON Syntax Errors in jobs.json

At some point, you'll want to edit your cron jobs directly in jobs.json — maybe to bulk-edit multiple jobs or tweak something the CLI doesn't easily expose. This is where people introduce silent syntax errors that prevent the gateway from loading any jobs at all.

Fix: Always validate JSON before saving.

# Find your jobs.json location
find ~/.openclaw -name "jobs.json" 2>/dev/null

# Validate before saving
cat ~/.openclaw/jobs.json | python3 -m json.tool

# If it outputs formatted JSON: valid ✓
# If it throws an error: find and fix the syntax issue before restarting the gateway

Common JSON gotchas: trailing commas after the last item in an array or object, unescaped quotes inside strings, missing closing brackets. If you edit manually, use a JSON-aware editor or validator.

Failure #5: Model Not Specified — Falls Back to a Default That Doesn't Exist

This one is subtle and maddening. You create a cron job without specifying a model. The job fires. OpenClaw tries to use the default model from your config. The default model is unavailable, deprecated, or not configured — and the job fails silently with no obvious error in the UI.

Fix: Always specify the model explicitly in your cron job commands.

# Explicitly specify model to avoid default fallback issues
openclaw cron add --every "6h" --name "inbox-check" --announce --best-effort-deliver \
  --model "anthropic/claude-sonnet-4-5" \
  --prompt "Check my email for urgent messages and summarize."

# Or use whatever model you know is active in your subscription
openclaw cron add --cron "0 9 * * 1-5" --name "weekday-brief" --announce \
  --model "anthropic/claude-opus-4-5" \
  --prompt "Morning briefing: calendar, priority emails, top 3 tasks."

After any OpenClaw or API subscription update, audit your existing cron jobs with openclaw cron list and confirm the specified models still exist. Model names change between versions.


🔍

Quick Diagnostic

Job not firing? Walk through this in order:

1

Gateway running?openclaw gateway status

2

Times in UTC? → EST is UTC-5, PST is UTC-8

3

Using isolated mode? → Main session may be dormant

4

Model specified? → Add --model explicitly

5

Has –announce + –best-effort-deliver? → Output may be lost without them

Working Examples You Can Copy

These are production-ready commands. Adjust models and prompts for your workflow.

Daily Morning Briefing (9 AM EST / 14:00 UTC, Weekdays)

openclaw cron add \
  --cron "0 14 * * 1-5" \
  --name "morning-briefing" \
  --announce \
  --best-effort-deliver \
  --model "anthropic/claude-sonnet-4-5" \
  --prompt "Good morning! Run my daily briefing: check unread emails from the last 18 hours and flag anything urgent, summarize today's calendar events, and list my top 3 priorities from HEARTBEAT.md. Keep it concise and actionable."

Every-6-Hours Inbox Check

openclaw cron add \
  --cron "0 0,6,12,18 * * *" \
  --name "inbox-check-6h" \
  --announce \
  --best-effort-deliver \
  --model "anthropic/claude-sonnet-4-5" \
  --prompt "Inbox check: scan email for messages received in the last 7 hours. Flag anything that needs a reply within 24 hours. If nothing urgent, reply with a brief 'inbox clear' status."

Weekly Report (Monday 8 AM UTC)

openclaw cron add \
  --cron "0 8 * * 1" \
  --name "weekly-report" \
  --announce \
  --best-effort-deliver \
  --model "anthropic/claude-opus-4-5" \
  --prompt "Generate my weekly report. Read memory/$(date -d 'last week' +%Y-%m-%d).md through memory/$(date +%Y-%m-%d).md if they exist. Summarize: (1) Key accomplishments last week, (2) Unfinished items to carry forward, (3) Top 5 priorities for this week. Format as a brief markdown report."

One-Shot Reminder (30 Minutes from Now)

openclaw cron add \
  --at "30m" \
  --name "call-reminder" \
  --announce \
  --delete-after-run \
  --model "anthropic/claude-sonnet-4-5" \
  --prompt "Reminder: your client call starts in 5 minutes. Pull up the notes from ~/docs/client-notes.md and give me a 3-bullet briefing."

How to Verify Your Cron Jobs Are Actually Running

Don't assume. Verify. Here's your diagnostic workflow:

# Step 1: Confirm gateway is running
openclaw gateway status

# Step 2: List all configured cron jobs
openclaw cron list

# Check output for:
# - Job name ✓
# - Schedule (correct UTC times?) ✓
# - Model specified ✓
# - Last run timestamp (did it fire when expected?) ✓
# - Next run timestamp (does it look right?) ✓

# Step 3: Check gateway logs for job execution entries
# Log location varies — check your openclaw config or:
find ~/.openclaw -name "*.log" -newer /tmp -ls 2>/dev/null
# Or
openclaw gateway logs --tail 100 | grep -i cron

A quick sanity-check approach: create a test job with --at "2m" and --announce. If it fires in roughly 2 minutes, your cron infrastructure is healthy. If it doesn't, the issue is at the gateway/daemon level, not the job syntax.

# Smoke test
openclaw cron add \
  --at "2m" \
  --name "cron-smoke-test" \
  --announce \
  --delete-after-run \
  --model "anthropic/claude-sonnet-4-5" \
  --prompt "Cron smoke test successful. Reply: CRON_OK [timestamp]"

The Auto-Announce Trap: Why Completed Jobs Don't Always Deliver

Here's a subtle failure mode that even experienced OpenClaw users hit: the cron job runs successfully, you can see it in the logs — but you never receive the output. The job completed into the void.

This happens because completion alone doesn't guarantee delivery. The agent finishes the task and generates output, but if you're not actively connected to the session that received it, the message sits undelivered.

The fix is two flags working together:

  • --announce — Tells the agent to actively push its output when done, rather than waiting passively for you to check
  • --best-effort-deliver — Attempts to deliver to your configured channel (Telegram, Discord, etc.) even if the session isn't actively open. Delivery isn't guaranteed, but it dramatically improves reliability.
# Without these flags: job runs, output disappears
openclaw cron add --every "6h" --name "inbox-check" \
  --prompt "Check email."

# With these flags: job runs, output delivered to you
openclaw cron add --every "6h" --name "inbox-check" \
  --announce --best-effort-deliver \
  --prompt "Check email."

Use both flags on every cron job where you actually want to see the output. The only exception is background maintenance jobs where output is logged but you don't need to read it in real-time.


Still Struggling? Here’s Where OpenClaw Cracked Helps

Cron jobs are one of OpenClaw's most powerful features — and one of its least documented. What I've laid out here covers the core failure modes, but there's a lot more depth: chaining jobs, handling failures gracefully, building reliable multi-agent workflows with cron as the backbone, and integrating cron with external services.

If your bottleneck is setup friction more than cron theory, OpenClaw Cracked is the faster path. It is a hosted deployment platform through the Claw Launcher dashboard: click deploy, paste your API key, and your agent is live in about 30 seconds — zero terminal and zero command-line setup. You still get the same OpenClaw power, plus 4 business-building skills, a 3-day live workshop, and an installation guarantee.

Pricing is $27 one-time plus $15/month hosting after a 14-day free trial. If you want execution without infrastructure friction, that’s the leverage.

🚀 Get Access to OpenClaw Cracked →


Quick Reference Cheat Sheet

# OPENCLAW CRON QUICK REFERENCE
# ─────────────────────────────

# Schedule types
--at "30m"              # 30 minutes from now (one-shot)
--at "2026-03-20T09:00Z"  # Specific UTC datetime (one-shot)
--every "6h"            # Every 6 hours (interval, resets on restart)
--cron "0 9 * * 1-5"   # Weekdays at 9 AM UTC (reliable)

# Flags for reliable delivery
--announce              # Push output when job completes
--best-effort-deliver   # Try to deliver to your channel
--delete-after-run      # Auto-cleanup for one-shot jobs

# Always specify model
--model "anthropic/claude-sonnet-4-5"

# Diagnostic commands
openclaw gateway status
openclaw cron list
openclaw gateway logs --tail 100

# Smoke test (fires in 2 min)
openclaw cron add --at "2m" --name "test" --announce \
  --delete-after-run --model "anthropic/claude-sonnet-4-5" \
  --prompt "CRON_OK"

Summary

OpenClaw cron jobs fail for predictable, fixable reasons. Here's the compressed version:

  1. Gateway not runningopenclaw gateway status, enable auto-start
  2. Wrong timezone → Everything is UTC. Convert before you schedule.
  3. Main session + no heartbeat → Use isolated sessions or configure heartbeat
  4. JSON syntax errors → Validate with python3 -m json.tool before saving
  5. Model fallback failure → Always specify --model explicitly
  6. Output not delivered → Add --announce --best-effort-deliver to every job

Get these right and OpenClaw cron becomes genuinely powerful — a background layer that keeps working while you're not watching. That's the goal. Good luck.


Related OpenClaw Articles

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top