From 1b64548caf6a1fdd07805e798458ba290207e72b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Feb 2026 11:35:52 +0100 Subject: [PATCH] fix: serialize cron force-run persistence --- src/cron/service/ops.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cron/service/ops.ts b/src/cron/service/ops.ts index e4ecbf741db..9d369766e43 100644 --- a/src/cron/service/ops.ts +++ b/src/cron/service/ops.ts @@ -209,11 +209,20 @@ export async function run(state: CronServiceState, id: string, mode?: "due" | "f } if (forced) { // Fire-and-forget: don't block the caller waiting for job completion - void executeJob(state, job, now, { forced }).then(() => { - recomputeNextRuns(state); - persist(state).catch(() => {}); - armTimer(state); - }); + void executeJob(state, job, now, { forced }) + .then(async () => { + await locked(state, async () => { + recomputeNextRuns(state); + await persist(state); + armTimer(state); + }); + }) + .catch((err) => { + state.deps.log.warn( + { err: err instanceof Error ? err.message : String(err), jobId: job.id }, + "cron: force run persistence failed", + ); + }); return { ok: true, ran: true } as const; } await executeJob(state, job, now, { forced });