Hmbown/CodeWhale · error · anyhow::Error

CRON EXPR must have exactly 5 fields: minute hour day-of-mon

Error message

CRON EXPR must have exactly 5 fields: minute hour day-of-month month day-of-week

What it means

ParsedCronExpr::parse splits EXPR on whitespace and requires exactly five fields (minute hour day-of-month month day-of-week). Six-field expressions with a leading seconds field or trailing year, and truncated four-field expressions, are rejected before any field is parsed.

Source

Thrown at crates/tui/src/automation_manager.rs:655

        }
    }
    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 0c42157ee5)

Solutions

  1. Drop the leading seconds field: */17 * * * *
  2. Drop a trailing year field if present
  3. Count whitespace-separated tokens before submitting (must be 5)
  4. Pre-validate with AutomationSchedule::parse_rrule("FREQ=CRON;EXPR=...")

Example fix

// before
rrule = "FREQ=CRON;EXPR=0 */17 * * * *"

// after
rrule = "FREQ=CRON;EXPR=*/17 * * * *"
Defensive patterns

Strategy: validation

Validate before calling

fn is_five_field_cron(expr: &str) -> bool {
    expr.split_whitespace().count() == 5
}

Prevention

When it happens

Trigger: EXPR='0 */17 * * * *' (Quartz-style seconds prefix); EXPR='*/17 * * *' (four fields); shell quoting that drops a field when passing the automation tool input.

Common situations: Porting crontabs from Quartz/cronie variants allowing 6-7 fields; quoting mistakes; hand-truncated examples from docs.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/7a6f9399749d4368. Report an issue: GitHub.