openclaw - ✅(Solved) Fix [Bug]: Cron job not resumed after restart when interrupted during execution [2 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#60495Fetched 2026-04-08 02:50:23
View on GitHub
Comments
2
Participants
2
Timeline
16
Reactions
0
Timeline (top)
referenced ×8commented ×2cross-referenced ×2labeled ×2

When OpenClaw restarts(first restart) while a cron job is still running, the job is not resumed or retried after startup. Instead, it is silently skipped and only runs after a subsequent restart(【second】 restart) under certain conditions.

This behavior can lead to missed executions without any explicit error.

Error Message

This behavior can lead to missed executions without any explicit error.

Root Cause

When OpenClaw restarts(first restart) while a cron job is still running, the job is not resumed or retried after startup. Instead, it is silently skipped and only runs after a subsequent restart(【second】 restart) under certain conditions.

This behavior can lead to missed executions without any explicit error.

Fix Action

Fixed

PR fix notes

PR #60583: fix(cron): resume interrupted recurring jobs on first restart

Description (problem / solution / changelog)

Closes #60495

Summary

  • When a gateway restart interrupts a running cron/every job, the job is now re-executed as part of startup catch-up on the first restart instead of requiring a second restart to recover.
  • One-shot (schedule kind "at") jobs preserve the existing behavior and are not retried after interruption.

Root Cause

The start function in src/cron/service/ops.ts collected all jobs with a stale runningAtMs marker into startupInterruptedJobIds and passed them to runMissedJobs as skipJobIds. This explicitly excluded interrupted jobs from startup catch-up. After runMissedJobs skipped them, recomputeNextRuns advanced their nextRunAtMs into the future, so the normal timer tick also would not fire them. Only a second restart (where runningAtMs was already cleared) allowed runMissedJobs to pick them up via the missed-slot detection path.

Fix

Changed the skip list to only include interrupted one-shot jobs. Interrupted recurring jobs (cron/every) now have their runningAtMs cleared and are immediately eligible for startup catch-up, since their nextRunAtMs is still past-due (the incomplete run never reached applyJobResult).

Changes

src/cron/service/ops.ts — replaced blanket startupInterruptedJobIds skip with interruptedOneShotIds that only collects one-shot jobs.

src/cron/service/ops.test.ts — updated the stale-running-marker test to expect the interrupted cron job to be replayed on first restart.

src/cron/service.restart-catchup.test.ts — updated the stale-marker test to expect the interrupted cron job to run and verify its lastStatus and lastRunAtMs are set.

Test Plan

  • npx vitest run src/cron/service.restart-catchup.test.ts — 8/8 pass
  • npx vitest run src/cron/service/ops.test.ts — 5/5 pass
  • npx vitest run src/cron/service.issue-regressions.test.ts — 43/43 pass
  • npx vitest run src/cron/service.issue-13992-regression.test.ts — 6/6 pass
  • npx vitest run src/cron/service.every-jobs-fire.test.ts — 3/3 pass
  • No lint errors on touched files

Risks and Mitigations

  • Interrupted recurring jobs now re-execute on first restart. This is the intended fix. Previously they were silently skipped, causing data gaps for users relying on scheduled tasks. The interrupted run never completed, so retrying is the correct behavior.
  • One-shot behavior preserved. Interrupted one-shots are still skipped, matching the existing design choice that one-shots are fire-and-forget.

Joel Nishanth · offlyn.AI

Made with Cursor

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/cron/service.restart-catchup.test.ts (modified, +10/-8)
  • src/cron/service/ops.test.ts (modified, +5/-4)
  • src/cron/service/ops.ts (modified, +13/-4)

PR #60615: fix(cron): replay interrupted recurring jobs on first restart

Description (problem / solution / changelog)

Summary

When OpenClaw restarts while a recurring cron job is running, the job is not retried on startup. It is only caught on a second restart when runMissedJobs() finds the next scheduled time past due again.

Root cause: In start() (src/cron/service/ops.ts), all interrupted jobs — regardless of schedule kind — are added to startupInterruptedJobIds and skipped by runMissedJobs(). After the skip, recomputeNextRuns() advances nextRunAtMs to the next future slot without executing the missed run.

Fix: Only add one-shot (kind === "at") jobs to the skip set. Recurring jobs (cron/every) are now eligible for startup catchup via runMissedJobs(), which already handles them correctly when their nextRunAtMs is past due.

  • Updated restart-catchup test to verify interrupted recurring jobs ARE replayed
  • One-shot (at) job test remains unchanged (still skipped on restart)

Fixes #60495

Test plan

  • Existing test "replays interrupted recurring cron jobs on startup" passes (updated from previous "clears stale running markers" test)
  • Existing test "does not replay interrupted one-shot jobs on startup" still passes
  • Manual: create a cron job, restart while running, verify it retries on first restart

🤖 Generated with Claude Code

Changed files

  • src/cron/service.restart-catchup.test.ts (modified, +10/-5)
  • src/cron/service/ops.ts (modified, +5/-1)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When OpenClaw restarts(first restart) while a cron job is still running, the job is not resumed or retried after startup. Instead, it is silently skipped and only runs after a subsequent restart(【second】 restart) under certain conditions.

This behavior can lead to missed executions without any explicit error.

Steps to reproduce

1.	Create a cron job (e.g. scheduled at 09:00).
2.	Let the job start running.
3.	Restart OpenClaw while the job is still in progress (e.g. at 09:01).
4.	Wait for scheduler ticks after restart.
5.     You will see the job`s nextRunAtMs (jobs.json) changed even the job did not complete.
6.     the job won`t be trigger in recent time(before the new nextRunAtMs) until you restart again.
7.      After you restart again(second restart), the job runs immediately at the runMissedJobs func

Expected behavior

1. The interrupted job should be detected as missed and re-executed after restart(first restart)
    2. Or the job should run on the next armed timer after cron service started

Actual behavior

On first restart:
•	runningAtMs is cleared (cron: clearing stale running marker on startup)
•	The job is added to startupInterruptedJobIds
•	runMissedJobs skips these jobs
•	Scheduler does not re-run the job
The job is not executed again during normal scheduler ticks
Only after a second restart, the job may be detected as missed and executed

OpenClaw version

2026.3.24

Operating system

Docker on MacOS 15.5

Install method

docker-setup.sh

Model

all

Provider / routing chain

all

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

•	Missed cron executions without visibility
•	Potential data inconsistency or lost side effects
•	Particularly problematic for critical or non-idempotent jobs

Additional information

Observed behavior suggests: 1. Interrupted jobs are excluded during startup recovery: runMissedJobs(state, { skipJobIds: startupInterruptedJobIds }) src/cron/service/ops.ts 2. Missed job detection via previousRunAtMs is effectively disabled by default: if (!params.allowCronMissedRunByLastRun || job.schedule.kind !== "cron") src/cron/service/timer.ts Since allowCronMissedRunByLastRun is undefined, the condition short-circuits and skips missed detection. 3. recomputeNextRuns advances nextAt, making the job appear as if it already ran.

extent analysis

TL;DR

The issue can be mitigated by modifying the runMissedJobs function to include interrupted jobs or by setting allowCronMissedRunByLastRun to enable missed job detection.

Guidance

  • Review the runMissedJobs function in src/cron/service/ops.ts to understand why interrupted jobs are excluded during startup recovery.
  • Consider setting allowCronMissedRunByLastRun to true to enable missed job detection via previous run time, as indicated in src/cron/service/timer.ts.
  • Investigate the recomputeNextRuns function to determine why it advances nextAt for interrupted jobs, making them appear as if they already ran.
  • Evaluate the impact of modifying the startupInterruptedJobIds logic to include these jobs in the startup recovery process.

Example

No specific code example is provided due to the complexity of the issue and the need for a thorough review of the affected code paths.

Notes

The provided information suggests that the issue is related to the handling of interrupted cron jobs during OpenClaw restarts. However, without further details on the implementation of the runMissedJobs, recomputeNextRuns, and startupInterruptedJobIds logic, it is challenging to provide a definitive solution.

Recommendation

Apply a workaround by setting allowCronMissedRunByLastRun to true to enable missed job detection, as this seems to be a critical factor in the observed behavior. This change may help mitigate the issue of missed cron executions without requiring significant modifications to the underlying codebase.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

  1. The interrupted job should be detected as missed and re-executed after restart(first restart) 2. Or the job should run on the next armed timer after cron service started

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Cron job not resumed after restart when interrupted during execution [2 pull requests, 2 comments, 2 participants]