#2646·BrowserOS

Scheduled task catch-up skips hourly and minute jobs after any run in the last 24 hours

Author: avinashgolaCreated Sep 9, 2026Updated Sep 9, 2026

Summary

runMissedJobs() uses a fixed 24-hour recent-run window for every schedule type. That is correct-ish for daily jobs, but it means hourly and minute-based jobs can miss due executions after the browser/extension has been asleep or restarted.

Evidence

In packages/browseros-agent/apps/app/entrypoints/background/scheduledJobRuns.ts, the missed-job loop computes:

typescript
const cutoff = now - TWENTY_FOUR_HOURS_MS
...
const hasRecentRun = runs.some(
  (r) => r.jobId === job.id && new Date(r.startedAt).getTime() > cutoff,
)
if (hasRecentRun) continue

Only after that does it look at scheduleType / scheduleInterval for hourly and minute jobs. So a job scheduled every 5 minutes with a run from an hour ago is considered recently run and skipped, even though many intervals were missed.

createAlarmFromJob() also recreates interval alarms from "now" when missing:

typescript
if (job.scheduleType === 'minutes' && job.scheduleInterval) {
  time = {
    delayInMinutes: job.scheduleInterval,
    periodInMinutes: job.scheduleInterval,
  }
}

That makes the startup catch-up path important: if the alarm was missing while the app was down, the next run is delayed another full interval and the missed due run is not recorded.

Repro sketch

  1. Create a scheduled task with scheduleType: 'minutes' and scheduleInterval: 5.
  2. Let it run once.
  3. Keep BrowserOS/extension inactive long enough to miss at least one interval, for example 30-60 minutes.
  4. Start BrowserOS again so runMissedJobs() runs.
  5. The task is skipped because it has a run in the last 24 hours, even though it is overdue by its configured interval.

Expected

Missed-job detection should use the job's actual cadence:

  • daily: compare against today's scheduled time / last daily window
  • hourly/minutes: compare lastRunAt or latest run time against scheduleInterval

Actual

Any run in the previous 24 hours suppresses catch-up for all schedule types.