affaan-m/ECC · error · anyhow::Error
cron expression `{expr}` did not yield a future run time
Error message
cron expression `{expr}` did not yield a future run time What it means
The next_schedule_run_at function parses a cron expression and calls .after(&after).next() to find the next future occurrence. If the iterator yields None — meaning no future run time exists for the given expression relative to the current time — the function bails. This is distinct from a parse error: the expression is syntactically valid but produces no future triggers.
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 01e15490f0)
Solutions
- Test the cron expression with a standalone cron parser to verify it produces future dates
- Check for impossible date constraints like '0 0 31 2 *' (February 31st)
- If the expression references a specific year that has passed, remove the year field or update it
- Validate the schedule at config-load time by computing the next run and failing early
Example fix
// before let schedule = "0 0 31 2 *"; // Feb 31 — impossible date let next = next_schedule_run_at(schedule, Utc::now())?; // after let schedule = "0 0 1 3 *"; // March 1st — valid let next = next_schedule_run_at(schedule, Utc::now())?;
Defensive patterns
Strategy: validation
Validate before calling
fn cron_has_future_run(expr: &str, after: DateTime<Utc>) -> bool {
parse_cron_schedule(expr)
.ok()
.and_then(|sched| sched.after(&after).next())
.is_some()
} Prevention
- Test cron expressions with a future-date computation before persisting them in config
- Check for impossible date constraints (Feb 31, Apr 31, etc.) in schedule fields
- Validate schedules at config-load time by computing the next run
When it happens
Trigger: Calling next_schedule_run_at with a valid cron expression whose CronSchedule iterator returns None for .after(&after).next().
Common situations: Cron expression with an impossible date constraint (e.g., Feb 31). Expression bounded by year that has already passed. Edge case in the cron crate where certain field combinations produce an empty iteration.
Related errors
- invalid cron expression `{trimmed}`: expected 5, 6, or 7 fie
- ECC_PROJECT_DIR must be a child path within /workspace.
- Unknown argument: ${arg}
- Unable to infer ECC repo root from install-state operations
- Invalid ECC repo root: missing package.json at ${packageJson
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/6f6680c714747175.
Report an issue: GitHub.