Install
openclaw skills install cron-helper-mayf3Configure, diagnose, and fix OpenClaw cron jobs. Activate when user mentions: cron, scheduled tasks, periodic jobs, timing issues, heartbeat vs cron, or any time-based automation.
openclaw skills install cron-helper-mayf3OpenClaw cron 定时任务配置、诊断和修复。
Every cron job fires in a brand-new isolated session with ZERO memory of previous runs.
The agent has no conversation history, no memory of what it did last time, and CANNOT ask the user questions. This means:
Prompt: "检查邮件,看看有没有重要的"
→ Agent checks email, finds nothing, outputs "没有新邮件"
→ Nothing saved. No state recorded.
→ Next run: same check, same "没有新邮件", forever identical
→ If something WAS important last run, nobody knows now
Prompt: "检查未读邮件。将新邮件摘要追加到 workspace/memory/email-log.md。
如果发现标记为紧急的邮件,立即发送通知到飞书群。
上次检查过的邮件ID记录在 workspace/memory/email-cursor.json。"
→ Agent reads cursor to know where it left off
→ Agent checks NEW emails since cursor
→ Agent writes updated cursor
→ Agent appends summary to log
→ Next run: picks up from cursor, never re-processes
Every cron prompt MUST follow at least one of these patterns:
| Pattern | How | Example |
|---|---|---|
| Cursor/Checkpoint | Read/write a pointer file tracking progress | memory/cursor.json with lastCheckTime or lastId |
| Append Log | Append results to a growing log file | memory/email-log.md, memory/daily-reports/2026-05-16.md |
| Idempotent Check | Compare current state vs saved baseline, only act on delta | Read memory/last-status.json, compare, update if changed |
| Time-windowed | Use current time to query only new data | date -v-1H to check last hour, write results to file |
| Counter/Tracker | Maintain a counter or running tally | memory/consecutive-failures.txt to trigger escalation |
Before writing ANY cron prompt, ensure it answers:
CLI 默认 timeout=30s,这对任何 real task 都太短了。每次创建 cron job 时必须显式设置 timeout。
| 任务类型 | 推荐 timeout |
|---|---|
| 简单报告(拉数据+输出) | 60-120s |
| 中等任务(读文件+分析+写文件) | 300-600s |
| 复杂任务(查多个数据源+多步分析) | 600-1200s |
| 大规模任务(处理积压数据) | 1200-1800s |
必须在 payload 和 CLI 中同时指定:
# CLI 用 --timeout-seconds 参数
openclaw cron add --timeout-seconds 600 ...
# payload 中也要写
"payload": { "kind": "agentTurn", "message": "...", "timeoutSeconds": 600 }
经验教训:ceo-agent 的每日随想分析任务默认 300s,前2天跑成功了,但数据积压后持续超时4天。改为 1200s 后解决。
A cron prompt is a standalone instruction to an amnesiac agent. It must contain:
Good prompt template:
执行 [任务描述]。
- 读取上次状态:[文件路径]
- 执行检查/操作:[具体步骤]
- 保存本次状态:[文件路径]
- 如果发现 [异常情况],[自动处理方式]
- 将结果追加到 [日志路径]
Bad prompt:
检查一下系统状态 ← 太模糊,没有落盘,没有状态
| Heartbeat | Cron | |
|---|---|---|
| Location | workspace/HEARTBEAT.md | ~/.openclaw/cron/jobs.json |
| Precision | ~30 minutes | Exact to second |
| Context | Has conversation context | Stateless isolated session |
| Best for | Bulk checks, monitoring | Precise timing, independent tasks |
Choose Cron when: precise timing, self-contained task, no conversation context needed Choose Heartbeat when: bulk checks across areas, needs recent conversation context
{
"id": "daily-report-001",
"agentId": "report-agent",
"name": "每日报告",
"enabled": true,
"schedule": { "kind": "cron", "expr": "0 10 * * *", "tz": "Asia/Shanghai" },
"payload": { "kind": "agentTurn", "message": "..." },
"delivery": { "mode": "announce", "channel": "feishu", "to": "chat:oc_xxx" }
}
Every job MUST have: id, agentId, name, enabled, schedule, payload.kind="agentTurn", payload.message, delivery.channel, delivery.to.
┌────────── minute (0-59)
│ ┌────────── hour (0-23)
│ │ ┌────────── day of month (1-31)
│ │ │ ┌────────── month (1-12)
│ │ │ │ ┌────────── day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *
Common patterns:
0 10 * * * — Daily at 10:00*/5 * * * * — Every 5 minutes0 */2 * * * — Every 2 hours*/30 0-8 * * * — Every 30min during 0:00-8:30 (night hours)0 9,17 * * * — Twice daily at 9AM and 5PM| # | Error | Fix |
|---|---|---|
| 1 | Missing delivery.channel + delivery.to | Must have BOTH: "channel": "feishu", "to": "chat:oc_xxx" |
| 2 | delivery.channel = "last" | "last" is NOT valid. Use "feishu" or "discord" |
| 3 | Missing payload.kind | Must be "agentTurn" |
| 4 | Using peer object in delivery | Use to string, not peer object |
| 5 | Missing schedule.tz | Always set "tz": "Asia/Shanghai" |
| 6 | jq redirect overwrite (jq '...' file > file) | Write to temp file first, then mv |
| 7 | Vague prompt with no state persistence | See "Statefulness Design Rules" above |
cp ~/.openclaw/cron/jobs.json ~/.openclaw/cron/jobs.json.backup-$(date +%Y%m%d-%H%M%S)scripts/validate-jobs-syntax-v2.sh| User Says | Scope | jq Pattern |
|---|---|---|
| "你的定时任务" | Only jobs with YOUR agentId | select(.agentId == "your-agent") |
| "每日报告任务" | Jobs matching that name | select(.name | contains("每日报告")) |
| "所有定时任务" | ALL jobs (user said "所有") | .jobs[] |
| Unclear | ASK first | — |
{
"payload": {
"kind": "agentTurn",
"message": "生成今日学习报告。1) 读取 memory/learning-queue.json 获取待研究主题队列。2) 研究队首主题,撰写笔记保存到 learning/YYYY-MM-DD.md。3) 从队列中移除已完成主题,追加新发现到队列。4) 将报告摘要发送到飞书群。如果队列为空,主动从 trending topics 中选择一个加入队列。"
}
}
{
"payload": {
"kind": "agentTurn",
"message": "检查服务健康状态。读取 memory/last-health-status.json 作为基线。对每个服务执行健康检查。如果状态与基线不同:更新基线文件,发送变更通知到飞书群。如果状态相同且全部正常:更新 last-check 时间戳,不发消息(避免噪音)。如果连续3次失败:发送告警并记录到 memory/alert-log.md。"
}
}
{
"payload": {
"kind": "agentTurn",
"message": "检查系统状态"
}
}
Why broken: No state file, no decision authority, no persistence. Every run produces identical output.
# 1. Check gateway status
openclaw gateway status
# 2. Validate jobs.json syntax
cat ~/.openclaw/cron/jobs.json | jq .
# 3. Run validation script
~/.openclaw/skills/cron-helper/scripts/validate-jobs-syntax-v2.sh
# 4. Check gateway logs for cron errors
openclaw gateway logs | grep -i cron
For detailed troubleshooting, see references/troubleshooting.md.
For full syntax specification, see references/syntax-guide.md.
For validation scripts, see scripts/.
{
"id": "TODO-unique-id",
"agentId": "TODO-agent-id",
"name": "TODO-任务描述",
"enabled": true,
"schedule": { "kind": "cron", "expr": "TODO * * * *", "tz": "Asia/Shanghai" },
"sessionTarget": "isolated",
"wakeMode": "now",
"payload": {
"kind": "agentTurn",
"message": "TODO-完整自包含指令:读取[状态文件]→执行[操作]→保存[状态文件]→如果[异常]则[自动处理]",
"timeoutSeconds": 300
},
"delivery": { "mode": "announce", "channel": "feishu", "to": "chat:oc_TODO" }
}
Before submitting: Run scripts/validate-jobs-syntax-v2.sh on the new config.