fix(cron): prevent premature cron job fire on restart (#60985)#2
Open
fix(cron): prevent premature cron job fire on restart (#60985)#2
Conversation
…penclaw#53395) Merged via squash. Prepared head SHA: 31f2396 Co-authored-by: drvoss <3031622+drvoss@users.noreply.github.com> Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com> Reviewed-by: @altaywtf
…d ping intervals (openclaw#56646) Merged via squash with admin override. Prepared head SHA: f1c91d5 Note: required red lanes are currently inherited from latest origin/main, not introduced by this PR. Co-authored-by: hsiaoa <70124331+hsiaoa@users.noreply.github.com> Co-authored-by: frankekn <4488090+frankekn@users.noreply.github.com> Reviewed-by: @frankekn
…penclaw#59911) Merged via squash. Prepared head SHA: a67bcaa Co-authored-by: ejames-dev <180847219+ejames-dev@users.noreply.github.com> Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com> Reviewed-by: @hxy91819
…penclaw#60557) Merged via squash. Prepared head SHA: 637ff7d Co-authored-by: feniix <91633+feniix@users.noreply.github.com> Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com> Reviewed-by: @altaywtf
When the gateway client reconnects using a stored device token, it was defaulting to ["operator.admin"] scopes instead of preserving the previously authorized scopes from the stored token. This caused the operator device token to be regenerated without operator.read scope, breaking status/probe/health commands. This fix: 1. Loads the stored scopes along with the stored token in selectConnectAuth 2. Uses the stored scopes when reconnecting with a valid device token 3. Falls back to explicitly requested scopes or default admin-only scope when no stored scopes exist Fixes openclaw#46000
…odel (openclaw#58294) * fix(cron): prevent agent default model from overriding cron payload model (openclaw#58065) When a cron job specifies a model override via the Advanced settings, runWithModelFallback could silently fall back to the agent's configured primary model. This happened because fallbacksOverride was undefined when neither payload.fallbacks nor per-agent fallbacks were configured, causing resolveFallbackCandidates to append the agent primary as a last-resort candidate. A transient failure on the cron-selected model (rate limit, model-not-found, etc.) would then succeed on the agent default, making it appear as if the override was ignored entirely. Fix: when the cron payload carries an explicit model override, ensure fallbacksOverride is always a defined array (empty when no fallbacks are configured) so the agent primary is never silently appended. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: use stricter toEqual([]) assertion for fallbacksOverride Replace toBeDefined() + toBeInstanceOf(Array) with toEqual([]) to catch regressions where the array unexpectedly gains entries. Addresses review feedback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: preserve cron override fallback semantics (openclaw#58294) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…y ran Fixes a regression where a cron job that already ran at its scheduled time would incorrectly fire again immediately on gateway restart. Root cause: isRunnableJob() computed previousRunAtMs from nowMs instead of nextRunAtMs in the allowCronMissedRunByLastRun path. When nowMs is before the scheduled time, previousRunAtMs incorrectly returned yesterday's slot — the same as lastRunAtMs for a job that already ran. The condition previousRunAtMs > lastRunAtMs evaluated to false, but there was no guard to suppress the false-positive catch-up. Fix: compute previousRunAtMs from nextRunAtMs (correct context) and add a lastRunAtMs >= previousRunAtMs guard to prevent replay of a job that already ran (at or after its scheduled slot). Fixes openclaw#60985
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a regression where a cron job that already ran at its scheduled time would incorrectly fire again immediately on gateway restart.
Bug Description
When the gateway restarts before a cron job's scheduled time, the job was incorrectly identified as a "missed" job and fired immediately on startup catch-up, even though:
Root Cause: In
isRunnableJob(), theallowCronMissedRunByLastRunpath computedpreviousRunAtMsfromnowMsinstead of fromnextRunAtMs. WhennowMsis before the scheduled time (e.g., 01:24 AM for a 09:00 AM job),previousRunAtMsincorrectly returned yesterday's scheduled slot — the same aslastRunAtMs. The conditionpreviousRunAtMs > lastRunAtMsevaluated tofalse... but the subsequent guard was absent, allowing the false-positive catch-up.The Fix:
previousRunAtMsfromnextRunAtMsinstead ofnowMs— this correctly contexts the previous occurrence relative to the upcoming scheduled slotlastRunAtMs >= previousRunAtMsguard that returnsfalsewhen the job already ran (either exactly at the scheduled slot or late after it)Files Changed
src/cron/service/timer.ts— fixisRunnableJob()to compute previous occurrence fromnextRunAtMsand add run-guardsrc/cron/service/timer.regression.test.ts— regression test for issue [Bug] Cron jobs immediately fire on gateway restart instead of waiting for next scheduled time openclaw/openclaw#60985Impact
Related Issues
Fixes openclaw#60985