#8701: fix: default enabled to true for cron jobs created via tool API
stale
Cluster:
Cron Job Fixes
## Problem
Jobs created via the cron tool API (agent tool calls) do not auto-fire because `state.nextRunAtMs` is never computed.
## Root Cause
When `enabled` is omitted from the tool call (common — the tool description says it's optional with default `true`), `normalizeCronJobCreate()` does not apply a default. The job is created with `enabled: undefined`, and `computeJobNextRunAtMs()` checks `!job.enabled` which is truthy for `undefined`, returning `undefined` immediately.
The CLI path works because it explicitly sets `enabled: !opts.disabled` (defaulting to `true`).
## Fix
Add `enabled` to the `applyDefaults` block in `normalizeCronJobInput()`, consistent with how `wakeMode` and `sessionTarget` are already defaulted:
```typescript
if (typeof next.enabled !== "boolean") {
next.enabled = true;
}
```
## Tests
Added two test cases to `normalize.test.ts`:
- `defaults enabled to true when omitted` — confirms the fix
- `respects explicit enabled: false` — confirms we don't clobber intentional disabling
All 7 tests pass.
Fixes #8672
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes cron jobs created via the tool API failing to auto-fire when `enabled` is omitted. `normalizeCronJobInput()` now applies a default `enabled = true` when `applyDefaults` is set (used by `normalizeCronJobCreate()`), aligning behavior with the CLI path and allowing downstream scheduling logic (e.g., `computeJobNextRunAtMs()`) to compute `nextRunAtMs`.
The change is localized to the cron job normalization layer (`src/cron/normalize.ts`) and is covered by two new Vitest cases in `src/cron/normalize.test.ts` verifying both the defaulting behavior and that explicit `enabled: false` is preserved.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is small, well-scoped, and aligns defaulting behavior between tool API and CLI; added tests cover the new behavior and ensure `enabled: false` is not overridden.
- No files require special attention
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#8698: fix(cron): default enabled to true for new jobs
by emmick4 · 2026-02-04
86.8%
#9088: fix(cron): ensure nextRunAtMs is computed when enabled is undefined...
by divol89 · 2026-02-04
86.7%
#7984: fix undefined variable in cron
by ThunderDrag · 2026-02-03
84.0%
#2071: fix: accept JSON string for cron.add job parameter (#1940)
by andrescardonas7 · 2026-01-26
80.7%
#8811: fix(cron): handle atMs fallback for kind=at jobs
by hlibr · 2026-02-04
80.4%
#12131: fix(cron): ensure timer callback fires for scheduled jobs
by divol89 · 2026-02-08
79.9%
#18960: fix: don't disable one-shot cron jobs on skipped status
by jwchmodx · 2026-02-17
79.8%
#11813: fix(cron): ensure 'at' schedule type correctly registers nextWakeAt...
by leo-reifying · 2026-02-08
79.5%
#12086: fix(cron): ensure timer callback fires for scheduled jobs
by divol89 · 2026-02-08
78.7%
#12303: fix(cron): correct nextRunAtMs calculation and prevent timer stall
by colddonkey · 2026-02-09
78.6%