affaan-m/ECC · error
cron expression ` ` did not yield a future run time
Error message
cron expression `{expr}` did not yield a future run time What it means
Raised when a parsed cron expression cannot produce any next run time after the given anchor. Valid-looking expressions may still be unsatisfiable, e.g. Feb 30, or dates excluded by day-of-month/day-of-week restrictions. The scheduler refuses to register a schedule it can never fire.
Solutions
- Validate the cron expression with a checker before scheduling; remove impossible date fields (Feb 30)
- Use a simpler expression (e.g. daily wildcard) to confirm scheduling works, then tighten it
- Check that day-of-month and day-of-week fields are not mutually restrictive (use * in one)
Example fix
// before schedule: "0 0 30 2 *" // Feb 30 never exists // after schedule: "0 0 1 3 *" // March 1st instead
Defensive patterns
Strategy: validation
Validate before calling
use cron::Schedule;
let sched: Schedule = expr.parse()?;
if sched.after(&chrono::Utc::now()).next().is_none() {
anyhow::bail!("cron `{expr}` has no future occurrence");
} Try / catch
match next_cron_run(expr, now) {
Ok(t) => schedule_at(t),
Err(e) => eprintln!("bad schedule: {e}; fix the cron expression"),
} Prevention
- Validate cron strings with a parser/linter before saving config
- Avoid impossible dates (Feb 30) and over-restrictive day fields
- Prefer standard 5-field crontab syntax
When it happens
Trigger: Scheduling a session with a cron expression whose next occurrence after `now` does not exist (e.g. '0 0 30 2 *' — Feb 30) or whose only matching dates are in the past.
Common situations: Hand-written cron strings with impossible dates; copy-pasted cron from another tool using 6/7-field syntax with seconds misaligned; time-zone assumptions making the expected first run already past.
Related errors
- invalid cron expression
- agent profile inheritance cycle
- an active harness configuration already exists
- atomic promotion compare-and-swap failed
- atomic rollback compare-and-swap failed
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/6f6680c714747175.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/manager.rs:2382
fields => {
anyhow::bail!(
"invalid cron expression `{trimmed}`: expected 5, 6, or 7 fields but found {fields}"
)
}
};
CronSchedule::from_str(&normalized)
.with_context(|| format!("invalid cron expression `{trimmed}`"))
}
fn next_schedule_run_at(
expr: &str,
after: chrono::DateTime<chrono::Utc>,
) -> Result<chrono::DateTime<chrono::Utc>> {
parse_cron_schedule(expr)?
.after(&after)
.next()
.map(|value| value.with_timezone(&chrono::Utc))
.ok_or_else(|| anyhow::anyhow!("cron expression `{expr}` did not yield a future run time"))
}
pub async fn run_session(
cfg: &Config,
session_id: &str,
task: &str,
agent_type: &str,
working_dir: &Path,
) -> Result<()> {
let db = StateStore::open(&cfg.db_path)?;
let session = resolve_session(&db, session_id)?;
if session.state != SessionState::Pending {
tracing::info!(
"Skipping run_session for {} because state is {}",
session_id,
session.state
);View on GitHub (pinned to 8321021c54)