Skip to content

fix(cron): keep recurring backoff stable after reload#74068

Closed
ai-hpc wants to merge 1 commit into
openclaw:mainfrom
ai-hpc:fix/cron-invalid-pattern-errors
Closed

fix(cron): keep recurring backoff stable after reload#74068
ai-hpc wants to merge 1 commit into
openclaw:mainfrom
ai-hpc:fix/cron-invalid-pattern-errors

Conversation

@ai-hpc

@ai-hpc ai-hpc commented Apr 29, 2026

Copy link
Copy Markdown
Member

Summary

  • keep recurring cron error backoff on the fixed recurring schedule during reload/recompute
  • stop applying one-shot cron.retry.backoffMs to recurring jobs after reload
  • add regression coverage for an errored recurring job with custom one-shot retry backoff

Verification

  • pnpm test src/cron/service.jobs.test.ts -- --reporter=verbose
  • git diff --check
  • pnpm check:changed --base openclaw/main
    • passed through core/core-test typecheck
    • stopped at lint:core because oxlint config reports: Rule 'no-underscore-dangle' not found in plugin 'eslint'

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: M labels Apr 29, 2026
@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep open for explicit maintainer handling, not cleanup close: this member-authored draft is still draft/conflicting and now conflicts with the current main and release contract that recurring cron backoff honors configured cron.retry.backoffMs.

Root-cause cluster
Relationship: superseded
Canonical: #93051
Summary: Merged recurring-backoff work owns the config-preserving direction on current main and the latest release; this draft overlaps the same cron backoff contract but proposes default-only recompute behavior.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Close this PR as superseded by #93051.

So I’m closing this here and keeping the remaining discussion on #93051.

Review details

Best possible solution:

Close this PR as superseded by #93051.

Do we have a high-confidence way to reproduce the issue?

Yes for the review finding: source inspection shows the PR removes configured cron.retry.backoffMs from recompute while current main runtime, docs, release, and durable readback coverage preserve it. I did not run tests because this review is read-only.

Is this the best way to solve the issue?

No. The patch changes only recompute and would diverge from current runtime scheduling, docs, and release behavior; the safer path is to preserve configured backoff or make a coordinated maintainer-approved contract change.

Security review:

Security review cleared: The diff changes only cron scheduling logic and a focused test, with no dependency, workflow, secret, permission, package, or artifact execution surface touched.

AGENTS.md: found and applied where relevant.

What I checked:

  • linked superseding PR: fix(cron): honor configured retry.backoffMs for recurring error backoff floor #93051 (fix(cron): honor configured retry.backoffMs for recurring error backoff floor) is merged at 2026-06-19T19:35:43Z.
  • cluster evidence: the durable review links that PR in the work cluster or recommended risk path.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • Alix-007: Authored the merged recurring-backoff fix that made recurring error backoff honor configured cron.retry.backoffMs and added durable SQLite readback coverage. (role: recent fix author; confidence: high; commits: d508337637c8, 27ab3e3c2d58, 16fba65cb6ad; files: src/cron/service/timer.ts, src/cron/service/timer.backoff-config-readback.test.ts)
  • steipete: Authored the merged recurring transient cron retry behavior and docs that extended cron.retry behavior to recurring jobs. (role: adjacent feature author; confidence: high; commits: cd0bc5195389, 89fbe0dc7239, 00c9f811715d; files: src/cron/service/timer.ts, src/cron/service/timer.regression.test.ts, docs/gateway/configuration-reference.md)
  • mbelinky: Authored merged work on the same cron maintenance/recompute backoff boundary in jobs.ts and timer.ts. (role: adjacent scheduler backoff contributor; confidence: medium; commits: 190a4b48697b; files: src/cron/service/jobs.ts, src/cron/service/timer.ts)
  • hugenshen: Authored the merged one-shot retry policy and cron.retry config surface that later recurring behavior reused. (role: introduced retry config surface; confidence: medium; commits: ea3955cd78a9; files: src/cron/service/timer.ts, src/config/types.cron.ts, src/config/schema.help.ts)

Codex review notes: model internal, reasoning high; reviewed against 5361e5a0b455.

@greptile-apps

greptile-apps Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds gateway-level validation of cron expressions for both cron.add and cron.update handlers, rejecting invalid Croner expressions via computeNextRunAtMs before any service mutation occurs. The fix correctly addresses the disabled-job edge case where the absence of next-run computation allowed invalid schedules to be persisted.

The two new tests directly lock in the pre-mutation rejection contract for both the add and disabled-job update paths, complementing the existing post-mutation parse-error test.

Confidence Score: 5/5

Safe to merge — the fix is narrowly scoped to gateway pre-validation and backed by new targeted tests.

No P0 or P1 findings. The validation logic is straightforward, the placement in the handler sequence is correct (after schema/timestamp validation, before delivery assertion and service mutation), nil-schedule is safely short-circuited, and the catch-all in cronScheduleValidationError is acceptable given that every exception computeNextRunAtMs can throw for a cron-kind schedule is genuinely an invalid-request condition.

No files require special attention.

Reviews (4): Last reviewed commit: "fix(cron): reject invalid schedule edits..." | Re-trigger Greptile

Comment thread src/gateway/server-methods/cron.ts Outdated
Comment on lines +103 to +108
function isCronScheduleParseError(err: unknown): err is Error {
return (
(err instanceof TypeError || err instanceof RangeError) &&
(err.message.startsWith("CronPattern:") || err.message.startsWith("CronDate:"))
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Croner error detection tied to message string prefixes

isCronScheduleParseError detects Croner failures by matching the error message against "CronPattern:" and "CronDate:" prefixes. If a future Croner release rewords or restructures its error messages, the defensive catch in addCronJobWithValidation / updateCronJobWithValidation would silently stop working — Croner TypeError/RangeError instances that no longer match the prefix would fall through the throw err branch and revert to the original gateway-crash behavior. Consider adding a comment pinning the expected Croner version (or a snapshot of the exact prefix format) so the fragility is visible during dependency upgrades.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/server-methods/cron.ts
Line: 103-108

Comment:
**Croner error detection tied to message string prefixes**

`isCronScheduleParseError` detects Croner failures by matching the error message against `"CronPattern:"` and `"CronDate:"` prefixes. If a future Croner release rewords or restructures its error messages, the defensive catch in `addCronJobWithValidation` / `updateCronJobWithValidation` would silently stop working — Croner `TypeError`/`RangeError` instances that no longer match the prefix would fall through the `throw err` branch and revert to the original gateway-crash behavior. Consider adding a comment pinning the expected Croner version (or a snapshot of the exact prefix format) so the fragility is visible during dependency upgrades.

How can I resolve this? If you propose a fix, please make it concise.

@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 650363a to 9503c75 Compare April 29, 2026 05:21
@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 9503c75 to 29c1eb7 Compare April 29, 2026 11:40
@ai-hpc
ai-hpc marked this pull request as draft April 29, 2026 11:42
@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 29c1eb7 to 189784e Compare April 29, 2026 11:52
@ai-hpc ai-hpc changed the title fix(gateway): reject invalid cron patterns fix(cron): narrow croner parse error handling Apr 29, 2026
@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 8964ed6 to 42a2c40 Compare April 29, 2026 16:01
@ai-hpc ai-hpc changed the title fix(cron): narrow croner parse error handling fix(cron): reject invalid schedule edits before mutation Apr 29, 2026
@hclsys

This comment was marked as low quality.

@ai-hpc

ai-hpc commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

Thanks. I narrowed the PR body to #74459 and kept the fix at the gateway boundary so invalid cron schedules are rejected before cron.update can mutate disabled jobs.

@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 42a2c40 to d5e2045 Compare April 29, 2026 16:11
@ai-hpc
ai-hpc marked this pull request as ready for review April 29, 2026 16:13
@ai-hpc

ai-hpc commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

@greptile-apps

@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes:

The PR imports cron schedule computation into the gateway cron handler, validates cron schedules before cron.add and cron.update, and adds two gateway validation tests proving invalid cron add/update requests do not call the cron service.

Maintainer follow-up before merge:

This is an active contributor PR with a narrow, plausible fix and no clear blocking defect; the next action is maintainer review and targeted validation, especially deciding whether gateway-only validation is sufficient for the linked issue scope.

Review details

Best possible solution:

Land this gateway-boundary validation if maintainers accept the scope, then handle any broader service-level transactional hardening for pre-existing invalid persisted jobs as a separate, explicit follow-up if needed.

Acceptance criteria:

  • pnpm test src/gateway/server-methods/cron.validation.test.ts -- --reporter=verbose
  • pnpm check:changed --base origin/main

What I checked:

  • current_main_mutates_before_validation: On current main, cron.update validates the request envelope and then calls context.cron.update(jobId, patch); the cron service applies applyJobPatch(job, patch) before computing the next run, so invalid disabled-job cron schedules can be written before Croner parsing runs. (src/cron/service/ops.ts:356, 8cf724a381a3)
  • croner_parse_site: Cron syntax is parsed through computeNextRunAtMs, which resolves cron schedules by constructing new Cron(expr, { timezone, catch: false }); this is the dependency-backed validation path the PR reuses before service mutation. (src/cron/schedule.ts:32, 8cf724a381a3)
  • pr_adds_pre_service_validation: The PR adds validateCronSchedule / cronScheduleValidationError in the gateway handler and calls it before context.cron.add and context.cron.update, so invalid submitted cron schedules are rejected before the service can mutate state. (src/gateway/server-methods/cron.ts:93, d5e2045a2d92)
  • pr_test_coverage: The PR adds focused tests for invalid cron.add and disabled-job cron.update schedules, asserting the gateway returns INVALID_REQUEST and does not call the cron service mutation methods. (src/gateway/server-methods/cron.validation.test.ts:325, d5e2045a2d92)
  • related_issue_context: The linked bug report and maintainer comment in the PR discussion independently describe the disabled-job loophole and support gateway-layer pre-validation as the intended scope for this fix.
  • security_review: The PR diff touches only src/gateway/server-methods/cron.ts and src/gateway/server-methods/cron.validation.test.ts; it does not alter workflows, dependencies, lockfiles, package metadata, secrets handling, permissions, artifact downloads, or install/build scripts. (d5e2045a2d92)

Likely related people:

  • yelog: Authored merged cron gateway parse-error handling in fix(cron): catch croner parse errors in cron.add and cron.update handlers #74193, which is the current main behavior this PR builds on and complements. (role: recent adjacent fix author; confidence: high; commits: d2db67e6931b; files: src/gateway/server-methods/cron.ts, src/gateway/server-methods/cron.validation.test.ts)
  • steipete: Current checkout blame and prior ClawSweeper history place recent cron gateway and scheduler maintenance around the affected handler and schedule evaluation paths with this maintainer. (role: recent maintainer; confidence: medium; commits: 8055e744, d01cb7b65f39, 911cfe2adc27; files: src/gateway/server-methods/cron.ts, src/gateway/server-methods/cron.validation.test.ts, src/cron/schedule.ts)
  • vincentkoc: Prior related review context links recent cron service operation fixes to this contributor, and the underlying mutation behavior is in src/cron/service/ops.ts and src/cron/service/jobs.ts. (role: adjacent cron service maintainer; confidence: medium; commits: 924271385ba9, 2896107153e5; files: src/cron/service/ops.ts, src/cron/service/jobs.ts)

Remaining risk / open question:

  • This review was read-only, so I did not run the PR's tests locally; the verdict is based on source, PR diff, provided discussion, prior report context, and dependency call-site inspection.
  • The PR prevents newly submitted invalid cron schedules from reaching the service, but it does not make CronService.update transactional for externally corrupted or already-persisted invalid cron jobs; maintainers should decide whether that broader repair belongs in this PR or a follow-up.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8cf724a381a3.

@ai-hpc

ai-hpc commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

Thanks. I agree broader CronService transactional hardening or repair for already-persisted invalid jobs is separate from this PR. This PR intentionally fixes #74459 at the gateway boundary: submitted invalid cron schedules are rejected before cron.add / cron.update can mutate disabled jobs.

Local proof:
pnpm test src/gateway/server-methods/cron.validation.test.ts -- --reporter=verbose passed,
pnpm build passed, and an isolated gateway smoke confirmed the invalid disabled-job edit now returns INVALID_REQUEST while preserving the previous valid schedule in live state and jobs.json.

@ai-hpc

ai-hpc commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

@greptileai

@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from d5e2045 to 4da928c Compare April 29, 2026 20:29
@ai-hpc ai-hpc closed this Apr 30, 2026
@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from 4da928c to 3c9437a Compare April 30, 2026 05:40
@ai-hpc ai-hpc reopened this Apr 30, 2026
@ai-hpc ai-hpc changed the title fix(cron): reject invalid schedule edits before mutation test(cron): assert live disabled schedule rollback Apr 30, 2026
@ai-hpc
ai-hpc marked this pull request as draft April 30, 2026 05:46
@openclaw-barnacle openclaw-barnacle Bot removed the gateway Gateway runtime label Apr 30, 2026
@ai-hpc
ai-hpc force-pushed the fix/cron-invalid-pattern-errors branch from e56554d to 32ead20 Compare April 30, 2026 17:32
@ai-hpc ai-hpc changed the title test(cron): assert live disabled schedule rollback fix(cron): keep recurring backoff stable after reloa Apr 30, 2026
@ai-hpc ai-hpc changed the title fix(cron): keep recurring backoff stable after reloa fix(cron): keep recurring backoff stable after reload Apr 30, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 14, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 17, 2026
@steipete

Copy link
Copy Markdown
Contributor

Thanks @ai-hpc. Closing as superseded by the current cron retry contract. Commit 7d76e54f2bbd made reload recomputation preserve configured cron.retry.backoffMs from run end, and #93051 extended and proved that contract through execution and SQLite readback; both are shipped.

This draft removes the configured schedule during recomputation, so it would now regress current runtime and documented behavior rather than fix it. If a distinct reload defect remains, please open a focused current-main issue with before and after timing plus persisted-state evidence.

@steipete steipete closed this Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants