tinyhumansai/openhuman · error
No future occurrence found within active hours after 100,000
Error message
No future occurrence found within active hours after 100,000 attempts
What it means
For Schedule::Cron with active_hours, next_run_for_schedule walks candidate occurrences and returns the first inside the active window. If 100,000 consecutive candidates all fall outside the window it gives up: as configured, the job can never fire. validate_schedule calls this function, so the error typically surfaces at job create/update time.
Source
Thrown at src/openhuman/cron/schedule.rs:45
if active.contains(local_t) {
return Ok(next_utc);
}
tracing::debug!(
"[cron] next_run candidate {} outside active window {}–{}, advancing",
next_utc,
active.start,
active.end
);
current_from = next_utc;
} else {
return Ok(next_utc);
}
}
tracing::warn!(
"[cron] no occurrence found within active_hours for expr={} after 100,000 candidates",
expr
);
anyhow::bail!("No future occurrence found within active hours after 100,000 attempts")
}
Schedule::At { at } => Ok(*at),
Schedule::Every { every_ms } => {
if *every_ms == 0 {
anyhow::bail!("Invalid schedule: every_ms must be > 0");
}
let ms = i64::try_from(*every_ms).context("every_ms is too large")?;
let delta = ChronoDuration::milliseconds(ms);
from.checked_add_signed(delta)
.ok_or_else(|| anyhow::anyhow!("every_ms overflowed DateTime"))
}
}
}
pub fn validate_schedule(schedule: &Schedule, now: DateTime<Utc>) -> Result<()> {
match schedule {
Schedule::Cron {
expr,View on GitHub (pinned to 7491200858)
Solutions
- Widen active_hours so at least one expression fire time is inside it — or remove active_hours entirely
- Shift the expression into the window (e.g. '0 3 * * *' → '0 10 * * *' for a 09:00-17:00 window)
- Set the job's tz so expression and active_hours agree on the clock, then re-validate
Example fix
// before
Schedule::Cron { expr: "0 3 * * *".into(), tz: None, active_hours: Some("09:00-17:00".into()) }
// after
Schedule::Cron { expr: "0 10 * * *".into(), tz: None, active_hours: Some("09:00-17:00".into()) } Defensive patterns
Strategy: validation
Validate before calling
// Authoring-time check: the job must have a reachable next run before persisting validate_schedule(&schedule, Utc::now())?; // or directly: next_run_for_schedule(&schedule, Utc::now())?;
Try / catch
At job-create/update handlers, catch this bail distinctly and return 'schedule never fires within active_hours' so the UI can highlight the active-hours field rather than the expression (or vice versa).
Prevention
- Sanity-check that at least one expression fire time lies inside active_hours before saving
- State the timezone next to active-hours inputs to prevent local/UTC mix-ups
- Re-validate jobs after DST changes or window edits
When it happens
Trigger: An expression that only fires outside the window — e.g. expr '0 3 * * *' (03:00) with active_hours '09:00-17:00'; timezone mismatch between the expression's tz and the window's clock; a narrowed window that no longer contains any fire time.
Common situations: Setting active_hours in local time while the expression is evaluated in the job tz; editing the window after the expression was chosen; DST shifts pushing the fire time out of the window; copy-pasted active_hours from a different job.
Related errors
- Invalid schedule: every_ms must be > 0
- At least one of --expression, --tz, --command, or --name mus
- Cannot update expression/tz on a non-cron schedule
- Invalid schedule: 'at' must be in the future
- Invalid cron expression: {expression} (expected 5, 6, or 7 f
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/6ba104a41cbed346.
Report an issue: GitHub.