Hmbown/CodeWhale · error · anyhow::Error
Unable to compute next anchored HOURLY run
Error message
Unable to compute next anchored HOURLY run
What it means
For HOURLY schedules with a BYHOUR/BYMINUTE anchor, next_after_in_timezone computes candidates as anchor + steps*INTERVAL and tries up to MAX_HOURLY_SEARCH_STEPS steps, keeping only candidates that match the optional BYDAY filter and resolve to a real local time (DST-safe). If the bounded search never yields a resolvable candidate strictly after the requested instant — e.g. every candidate in the window falls in a nonexistent local time or misses the BYDAY filter — it gives up with this error instead of looping unbounded.
Source
Thrown at crates/tui/src/automation_manager.rs:482
.ok_or_else(|| anyhow::anyhow!("HOURLY schedule exceeded its range"))?;
if byday
.as_ref()
.is_none_or(|days| days.contains(&candidate_naive.weekday()))
&& let Some(candidate) =
resolve_local_datetime(timezone, candidate_naive)
{
let candidate = candidate.with_timezone(&Utc);
if candidate > after {
return Ok(candidate);
}
}
steps = steps
.checked_add(1)
.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");
}
View on GitHub (pinned to 0c42157ee5)
Solutions
- Switch to `FREQ=CRON;EXPR=...` for day-filtered daily/long-interval patterns — it expresses them directly.
- Reduce INTERVAL or drop BYDAY so candidates occur densely enough to land inside the search window.
- Pass an `after` close to the present; schedule previews far in the future can exhaust the step budget by themselves.
Example fix
// before
let s = AutomationSchedule::parse_rrule("FREQ=HOURLY;INTERVAL=24;BYDAY=MO,FR;BYHOUR=8;BYMINUTE=30")?;
let next = s.next_after(after, &tz)?; // may bail: Unable to compute next anchored HOURLY run
// after
let s = AutomationSchedule::parse_rrule("FREQ=CRON;EXPR=30 8 * * 1,5")?;
let next = s.next_after(after, &tz)?; Defensive patterns
Strategy: try-catch
Validate before calling
// Prefer CRON for day-filtered long-interval patterns before hitting search limits.
if interval_hours >= 24 && byday.is_some() {
anyhow::bail!("use FREQ=CRON;EXPR='M H * * DAYS' instead of HOURLY with INTERVAL>=24 + BYDAY");
} Type guard
fn anchored_hourly_searchable(interval_hours: u32, byday_filter: Option<&[chrono::Weekday]>) -> bool {
byday_filter.is_none() || interval_hours <= 12 // dense enough to land inside MAX_HOURLY_SEARCH_STEPS
} Try / catch
match schedule.next_after(after, &tz) {
Ok(next) => next,
Err(e) if e.to_string().contains("Unable to compute next anchored HOURLY run") => {
AutomationSchedule::parse_rrule("FREQ=CRON;EXPR=30 8 * * 1,5")?.next_after(after, &tz)?
}
Err(e) => return Err(e),
} Prevention
- Express day-filtered daily cadences as FREQ=CRON, not FREQ=HOURLY;INTERVAL=24;BYDAY=... .
- Keep HOURLY intervals small enough that matching weekdays occur within the bounded search window.
- Query next-run with `after` near the present; far-future previews can exhaust the step budget.
When it happens
Trigger: A large INTERVAL (e.g. INTERVAL=24 or more) with a BYDAY filter whose weekdays never align within MAX_HOURLY_SEARCH_STEPS candidate steps; or anchored candidates repeatedly landing in a skipped local time around a DST transition; or querying next_after with an `after` extremely far from the anchor so the window of steps is spent catching up.
Common situations: Emulating DAILY with FREQ=HOURLY;INTERVAL=24;BYDAY=MO,FR plus an anchor; timezone databases with unusual transitions; passing a projected/inserted `after` far in the future when previewing schedules.
Related errors
- Unable to compute next HOURLY run for BYDAY filter
- Unable to compute next WEEKLY run
- Invalid RRULE segment '{item}'
- Unsupported RRULE FREQ '{other}'. Supported: ONCE, HOURLY, W
- RRULE must include FREQ
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/93e2307880182a89.
Report an issue: GitHub.