Hmbown/CodeWhale · error · anyhow::Error
Unable to compute next HOURLY run for BYDAY filter
Error message
Unable to compute next HOURLY run for BYDAY filter
What it means
Thrown by the unanchored HOURLY branch of AutomationSchedule::next_after_in_timezone when a BYDAY filter cannot be satisfied. The code advances a candidate time by INTERVAL hours for up to 24*21 = 504 steps and bails if candidate.weekday() never appears in the BYDAY list. Because each step advances by INTERVAL hours, an INTERVAL that is a multiple of 168 (a whole number of weeks, e.g. 168 or 336) freezes the weekday, so a BYDAY list excluding that weekday can never match.
Source
Thrown at crates/tui/src/automation_manager.rs:498
.ok_or_else(|| anyhow::anyhow!("HOURLY schedule exceeded its range"))?;
}
bail!("Unable to compute next anchored HOURLY run");
}
let after_second = local_after.second();
let after_nanosecond = local_after.nanosecond();
let mut candidate = local_after + Duration::hours(i64::from(*interval_hours))
- Duration::seconds(i64::from(after_second))
- Duration::nanoseconds(i64::from(after_nanosecond));
if let Some(days) = byday {
for _ in 0..(24 * 21) {
if days.contains(&candidate.weekday()) {
return Ok(candidate.with_timezone(&Utc));
}
candidate += Duration::hours(i64::from(*interval_hours));
}
bail!("Unable to compute next HOURLY run for BYDAY filter");
}
Ok(candidate.with_timezone(&Utc))
}
Self::Weekly {
byday,
byhour,
byminute,
} => {
for day_offset in 0..15 {
let date = local_after.date_naive() + Duration::days(i64::from(day_offset));
if !byday.contains(&date.weekday()) {
continue;
}
let Some(candidate_naive) = date.and_hms_opt(*byhour, *byminute, 0) else {
continue;
};
if let Some(candidate) = resolve_local_datetime(timezone, candidate_naive)View on GitHub (pinned to 0c42157ee5)
Solutions
- Use FREQ=WEEKLY;BYDAY=MO;BYHOUR=H;BYMINUTE=M for once-per-week wall-clock schedules
- If HOURLY semantics are required, choose an INTERVAL that is not a multiple of 168 (e.g. 24), or include the frozen weekday in BYDAY
- Dry-run AutomationSchedule::parse_rrule plus a next-run computation before flipping an automation to Active
- Catch the error at the manager boundary and pause the automation instead of aborting the scheduling loop
Example fix
// before (weekday frozen, can never match) rrule = "FREQ=HOURLY;INTERVAL=168;BYDAY=MO" // after (weekly wall-clock schedule) rrule = "FREQ=WEEKLY;BYDAY=MO;BYHOUR=9;BYMINUTE=0"
Defensive patterns
Strategy: validation
Validate before calling
fn hourly_byday_reachable(rrule: &str) -> Result<bool, anyhow::Error> {
if let AutomationSchedule::Hourly { interval_hours, byday: Some(days), .. } =
AutomationSchedule::parse_rrule(rrule)?
{
if interval_hours > 0 && interval_hours % 168 == 0 {
// Weekday is frozen at the first candidate's weekday.
let first = chrono::Local::now()
+ chrono::Duration::hours(i64::from(interval_hours));
return Ok(days.contains(&first.weekday()));
}
}
Ok(true)
} Try / catch
match manager.update_automation(id, req) {
Ok(record) => { /* persisted with next_run_at */ }
Err(e) if e.to_string().contains("HOURLY run for BYDAY filter") => {
// Schedule can never fire: keep it paused and surface a config error.
tracing::warn!(%e, "unreachable HOURLY/BYDAY automation {id}");
}
Err(e) => return Err(e),
} Prevention
- Never encode weekly cadence as INTERVAL=168 under FREQ=HOURLY; use FREQ=WEEKLY
- Pre-validate rrule strings by parsing and computing the next run before setting status Active
- Treat any interval that is a whole number of weeks combined with BYDAY as a config smell
- Log automation id and rrule whenever next-run computation fails so bad rules are findable
When it happens
Trigger: Computing next_run_at for an Active automation (create_automation/update_automation with status Active) whose rrule is FREQ=HOURLY;INTERVAL=168;BYDAY=MO when the first candidate after 'now' is not a Monday: weekday never changes across 504 steps and next_after_with_anchor returns this error.
Common situations: Encoding a weekly intent as FREQ=HOURLY with INTERVAL=168 (assuming INTERVAL counts days); INTERVAL=24*N where N is a multiple of 7 combined with BYDAY; rrules copied from tools that accept multi-week hourly intervals.
Related errors
- BYDAY cannot be empty for WEEKLY schedules
- Unable to compute next anchored HOURLY run
- Unable to compute next WEEKLY run
- Invalid RRULE segment '{item}'
- Unsupported RRULE FREQ '{other}'. Supported: ONCE, HOURLY, W
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/d8533accfa5f9766.
Report an issue: GitHub.