Skip to content

Commit c19ceca

Browse files
fix: surface not-found when setEnabled races a deletion
The UPDATE now uses RETURNING and fails with "Schedule task not found." when zero rows changed, instead of reporting a toggle that was never persisted as a success. Co-Authored-By: Claude Fable 5 <[email protected]>
1 parent 543c414 commit c19ceca

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

‎apps/server/src/scheduledTasks/ScheduledTaskService.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,17 +750,23 @@ export const layer = Layer.effect(
750750
if (existing.enabled === input.enabled) return { task: existing };
751751
const now = yield* localNow;
752752
const next = nextRunAt({ enabled: input.enabled, schedule: existing.schedule }, now);
753-
yield* sql`
753+
// RETURNING so a task deleted between the load and this UPDATE is a
754+
// visible not-found error, not a false success.
755+
const updated = yield* sql<{ task_id: string }>`
754756
UPDATE scheduled_tasks
755757
SET enabled = ${input.enabled ? 1 : 0},
756758
next_run_at = ${next},
757759
updated_at = ${iso(now)}
758760
WHERE task_id = ${input.id}
761+
RETURNING task_id
759762
`.pipe(
760763
Effect.mapError((cause) =>
761764
taskError("Could not update schedule task.", { taskId: input.id, cause }),
762765
),
763766
);
767+
if (updated.length === 0) {
768+
return yield* taskError("Schedule task not found.", { taskId: input.id });
769+
}
764770
yield* notifyChanged;
765771
return {
766772
task: { ...existing, enabled: input.enabled, nextRunAt: next, updatedAt: iso(now) },

0 commit comments

Comments
 (0)