#cron help
1 messages · Page 1 of 1 (latest)
wow
@paper crow save me
max_beam@lenovobymagz:~$ openclaw cron list --json | jq '[.jobs[] | {name: .name, lastRun: .state.lastRunAtMs, nextRun: .state.nextRunAtMs, lastResult: .state.lastResult}]'
[
{
"name": "hourly-scan",
"lastRun": 1773343080548,
"nextRun": 1773346680548,
"lastResult": null
},
{
"name": "ai-stock-research",
"lastRun": 1773313200019,
"nextRun": 1773399600000,
"lastResult": null
},
{
"name": "crypto-research",
"lastRun": 1773314100019,
"nextRun": 1773400500000,
"lastResult": null
},
{
"name": "mc-trend-scout",
"lastRun": 1773315000013,
"nextRun": 1773401400000,
"lastResult": null
},
{
"name": "index-research",
"lastRun": 1773315021516,
"nextRun": 1773401400000,
"lastResult": null
},
{
"name": "mc-research",
"lastRun": 1773316800016,
"nextRun": 1773403200000,
"lastResult": null
},
{
"name": "mc-breakdowns",
"lastRun": 1773318600014,
"nextRun": 1773405000000,
"lastResult": null
},
{
"name": "mc-community",
"lastRun": 1773331200016,
"nextRun": 1773417600000,
"lastResult": null
}
]
lastResult being null here is basically a jq artifact: in current cron, the “what happened?” info isn’t stored on the job record (or that field is legacy / not populated). The job list gives you mostly scheduling state (lastRunAtMs, nextRunAtMs, enabled, schedule, etc). The actual outcomes live in run history.
Use run history instead:
openclaw cron list --json | jq '.jobs[] | {jobId: (.jobId // .id), name: .name}'
openclaw cron runs --id <jobId> --limit 20
# (add --json if you want to jq the run objects)
Docs refs:
- Cron jobs + where history is stored: https://docs.openclaw.ai/automation/cron-jobs (see “Storage & history”)
- “Cron not firing / no delivery” checklist: https://docs.openclaw.ai/automation/troubleshooting
If you paste the output of openclaw cron runs --id hourly-scan --limit 5 --json (or the non-json version), we can tell whether it’s running ok, being skipped as not-due, or running fine but with delivery.mode: "none" so nothing gets sent out.
Yep — that output is exactly what I’d expect if you’re jq’ing a field that isn’t populated anymore on the job state.
Next step is to look at the run history for a specific job (that’s where success/fail + error text lives):
# get the jobId for a name
jobId=$(openclaw cron list --json | jq -r '.jobs[] | select(.name=="hourly-scan") | (.jobId // .id)')
# inspect recent runs (this is the “lastResult” equivalent)
openclaw cron runs --id "$jobId" --limit 10 --json
If you paste the last ~2 runs for one job (json or table), we can tell whether it’s ok, being skipped, backing off, or failing delivery.
Yeah those huge numbers are just Unix epoch timestamps in milliseconds.
Two handy ways to make that output human-readable:
1) Don’t use --json (CLI already formats it)
openclaw cron list
2) Keep JSON, but convert ms → ISO8601 in jq
openclaw cron list --json | jq '[
.jobs[] | {
name,
lastRun: (if .state.lastRunAtMs then (.state.lastRunAtMs/1000 | todateiso8601) else null end),
nextRun: (if .state.nextRunAtMs then (.state.nextRunAtMs/1000 | todateiso8601) else null end)
}
]'
And yeah: lastResult being null is expected — the “result/outcome” lives in run history (openclaw cron runs --id <jobId>), not on the job state blob.
You’re not broken — lastResult just isn’t a thing on the job state anymore (or it’s legacy/unused), so it’ll stay null even when jobs are running fine.
What to do instead:
- Get the jobId
openclaw cron list --json | jq -r '.jobs[] | "\(.jobId // .id)\t\(.name)"'
- See what actually happened (success/fail/why)
openclaw cron runs --id <jobId> --limit 20
# add --json if you want to jq it
- (Optional) Fastest “last result” on-disk peek
Run history is stored at:
~/.openclaw/cron/runs/<jobId>.jsonl
So you can do:
tail -n 5 ~/.openclaw/cron/runs/<jobId>.jsonl
If you paste the output of openclaw cron runs --id <jobId> --limit 5 for one job (e.g. hourly-scan), I can tell you immediately whether it’s ok, skipped (not-due), backing off, or failing delivery.
Running that exact cron list ... lastResult command again won’t ever show anything new — .state.lastResult is just not populated, so it’ll stay null.
Do this instead (smallest possible next step):
openclaw cron list
That table output includes the job id. Then run:
openclaw cron runs --id <jobId> --limit 5
If you want it all in one go for hourly-scan: