Skip to content

fix(agent): guard runMissedJobs daily branch from premature execution#1019

Open
Akhilesh Arora (akhilesharora) wants to merge 1 commit into
browseros-ai:mainfrom
akhilesharora:fix/runmissedjobs-daily-startup
Open

fix(agent): guard runMissedJobs daily branch from premature execution#1019
Akhilesh Arora (akhilesharora) wants to merge 1 commit into
browseros-ai:mainfrom
akhilesharora:fix/runmissedjobs-daily-startup

Conversation

@akhilesharora
Copy link
Copy Markdown

Summary

  • The daily branch of runMissedJobs was missing the createdAt gate that the hourly/minutes branch right below it already had, so a brand-new daily task fires on the next startup instead of waiting for tomorrow's alarm.
  • Also add a Number.isFinite check for the parsed hours/minutes, so malformed scheduleTime strings ("abc", "", "9") skip instead of falling through with a NaN gate.

Design

The daily check at scheduledJobRuns.ts:176-181 only asked "has the scheduled HH:MM passed today?". For a job created today at 17:30 with scheduleTime: "09:00", that's true, so the gate fell through and the task ran immediately, even though createAlarmFromJob correctly scheduled the first alarm for tomorrow 09:00. The hourly/minutes branch right below (lines 183-193) already gates on createdAt; mirroring that here closes the daily case.

The Number.isFinite guard handles scheduleTime strings that don't parse cleanly. Without it, setHours(NaN, NaN, ...) yields an invalid Date and the gate always falls through, so a job with a malformed schedule fires on every alarm tick. Reachable via apps/server/src/tools/nudges.ts, which accepts any string for scheduleTime.

Test plan

Daily-gate logic in Node, with the fix applied:

$ node -e '
function dailyGate(scheduleTime, jobCreatedAtIso, now) {
    const [hours, minutes] = scheduleTime.split(":").map(Number);
    if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return true;
    const scheduledToday = new Date(now);
    scheduledToday.setHours(hours, minutes, 0, 0);
    if (now < scheduledToday.getTime()) return true;
    const createdAt = new Date(jobCreatedAtIso).getTime();
    if (createdAt > scheduledToday.getTime()) return true;
    return false;
}
const now = new Date("2026-05-17T18:00:00+02:00").getTime();
const createdToday = new Date("2026-05-17T17:30:00+02:00").toISOString();
const createdYesterday = new Date("2026-05-16T10:00:00+02:00").toISOString();
console.log("brand-new, scheduleTime 09:00:", dailyGate("09:00", createdToday, now) ? "skip (correct)" : "FIRES");
console.log("missed run from yesterday:", dailyGate("09:00", createdYesterday, now) ? "skip" : "FIRES (correct, intentional)");
console.log("malformed scheduleTime abc:", dailyGate("abc", createdYesterday, now) ? "skip (correct)" : "FIRES");
'
brand-new, scheduleTime 09:00: skip (correct)
missed run from yesterday: FIRES (correct, intentional)
malformed scheduleTime abc: skip (correct)

Legitimate missed runs (job created before today's scheduled time, browser was closed across it) still fire as intended.

Fixes #1018

A brand-new daily job created today after its scheduleTime fires on the
next startup instead of waiting for tomorrow's alarm. The daily branch
in runMissedJobs only checked whether HH:MM had passed today, not
whether the job existed before that time. Mirror the hourly/minutes
branch immediately below, which already gates on createdAt.

Also guard against scheduleTime values that don't parse as HH:MM
("abc", "", "9"). Without the Number.isFinite check, setHours(NaN, ...)
yields an invalid Date and the gate falls through on every alarm tick.
Reachable via LLM-generated nudges where scheduleTime is unvalidated.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 17, 2026

PR author is not in the allowed authors list.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 17, 2026

All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

@akhilesharora
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Daily scheduled task fires on browser startup if created after its scheduleTime

1 participant