Hmbown/CodeWhale · error · anyhow::Error
CRON EXPR must have exactly 5 fields: minute hour…
Error message
CRON EXPR must have exactly 5 fields: minute hour day-of-month month day-of-week
What it means
ParsedCronExpr::parse splits the EXPR on whitespace and requires exactly five fields — minute, hour, day-of-month, month, day-of-week — before validating each field. Any other count bails with this message describing the expected layout. It fires both when saving a CRON schedule and when next_after_in_timezone re-parses the stored expression.
Solutions
- Provide exactly five whitespace-separated fields: 'minute hour day-of-month month day-of-week' (e.g. '0 9 * * *').
- Drop the seconds field from 6-field cron expressions (this parser has minute granularity only).
- Use '*' for fields you don't want to constrain instead of omitting them.
Example fix
// before FREQ=CRON;EXPR="0 9 * * * *" // after FREQ=CRON;EXPR="0 9 * * *"
Defensive patterns
Strategy: validation
Validate before calling
fn valid_cron_expr(expr: &str) -> bool {
expr.split_whitespace().count() == 5
} Try / catch
match AutomationSchedule::parse(rrule) {
Ok(s) => save(s),
Err(e) if e.to_string().contains("exactly 5 fields") => show_cron_format_help(&e),
Err(e) => report(e),
} Prevention
- Reject 6-field (seconds) cron at input time with a clear message.
- Provide field-by-field inputs (minute, hour, dom, month, dow) and join them with spaces.
- Document that this parser supports standard 5-field cron only, minute granularity.
When it happens
Trigger: AutomationSchedule::parse with FREQ=CRON;EXPR=<expr> where split_whitespace yields != 5 fields: 6-field cron with seconds, 3-field shorthand, or an expression with collapsed/extra whitespace not intended as fields.
Common situations: Users pasting 6-field (with seconds) cron from systemd or Quartz; omitting a field (e.g. '0 9 *' meaning daily 9am); extra spaces normally fine but a missing field is not.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- context_window must be greater than 0
- CRON EXPR day-of-month/month combination can never occur
- CRON field contains an empty list item
- CRON field must not be empty
- CRON range start must be <= end
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/7a6f9399749d4368.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/automation_manager.rs:754
}
}
bail!("Failed to parse ONCE AT '{trimmed}'. Use local YYYY-MM-DDTHH:MM[:SS] or RFC3339")
}
#[derive(Debug, Clone)]
struct ParsedCronExpr {
minute: CronField,
hour: CronField,
day_of_month: CronField,
month: CronField,
day_of_week: CronField,
}
impl ParsedCronExpr {
fn parse(expr: &str) -> Result<Self> {
let fields: Vec<&str> = expr.split_whitespace().collect();
if fields.len() != 5 {
bail!(
"CRON EXPR must have exactly 5 fields: minute hour day-of-month month day-of-week"
);
}
let parsed = Self {
minute: CronField::parse(fields[0], 0, 59, CronNameMap::none(), "minute")?,
hour: CronField::parse(fields[1], 0, 23, CronNameMap::none(), "hour")?,
day_of_month: CronField::parse(fields[2], 1, 31, CronNameMap::none(), "day-of-month")?,
month: CronField::parse(fields[3], 1, 12, CronNameMap::month(), "month")?,
day_of_week: CronField::parse(fields[4], 0, 7, CronNameMap::weekday(), "day-of-week")?
.normalized_day_of_week(),
};
parsed.validate_date_space()?;
Ok(parsed)
}
fn matches(&self, candidate: NaiveDateTime) -> bool {
if !self.minute.contains(candidate.minute())
|| !self.hour.contains(candidate.hour())View on GitHub (pinned to 73e0f67d83)