Hmbown/CodeWhale · error

Invalid CRON {field_name} value '{raw}'

Error message

Invalid CRON {field_name} value '{raw}'

What it means

Thrown by the TUI automation scheduler while validating a CRON expression (`RRULE:FREQ=CRON;EXPR=...`). `parse_cron_atom` accepts exactly two token shapes for a cron field atom: a recognized 3-letter name (JAN-DEC for month, SUN-SAT for day-of-week, matched case-insensitively after trim) or an unsigned integer; anything else is rejected before the range check. The expression must have exactly 5 fields (minute 0-59, hour 0-23, day-of-month 1-31, month 1-12, day-of-week 0-7).

Source

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

    fn lookup(self, token: &str) -> Option<u32> {
        let needle = token.trim().to_ascii_uppercase();
        self.0
            .iter()
            .find_map(|(name, value)| (*name == needle).then_some(*value))
    }
}

fn parse_cron_atom(
    raw: &str,
    min: u32,
    max: u32,
    names: CronNameMap,
    field_name: &str,
) -> Result<u32> {
    let value = names
        .lookup(raw)
        .or_else(|| raw.parse::<u32>().ok())
        .ok_or_else(|| anyhow::anyhow!("Invalid CRON {field_name} value '{raw}'"))?;
    if !(min..=max).contains(&value) {
        bail!("CRON {field_name} value {value} is out of range {min}-{max}");
    }
    Ok(value)
}

fn weekday_to_cron(day: Weekday) -> u32 {
    match day {
        Weekday::Sun => 0,
        Weekday::Mon => 1,
        Weekday::Tue => 2,
        Weekday::Wed => 3,
        Weekday::Thu => 4,
        Weekday::Fri => 5,
        Weekday::Sat => 6,
    }
}

View on GitHub (pinned to 8880682c63)

Solutions

  1. Rewrite EXPR with exactly 5 space-separated fields: minute hour day-of-month month day-of-week.
  2. Use only 3-letter names (MON, FRI, JAN, OCT) or plain integers — e.g. `EXPR=0 9 * * MON-FRI` instead of `0 9 ? * MONDAY *`.
  3. Remove Quartz-only tokens (`L`, `W`, `?`, `#`, seconds field) and stray punctuation; check the offending field named in the message (`minute`, `hour`, `day-of-month`, `month`, `day-of-week`).
  4. Note that day-of-week accepts 0-7 (both 0 and 7 mean Sunday) and month names/numbers are 1-12.

Example fix

# before
RRULE:FREQ=CRON;EXPR=0 9 ? * MONDAY *
# after
RRULE:FREQ=CRON;EXPR=0 9 * * MON-FRI
Defensive patterns

Strategy: validation

Validate before calling

// Validate a cron atom before storing the automation schedule.
fn valid_cron_atom(raw: &str, min: u32, max: u32, names: &[(&str, u32)]) -> bool {
    let needle = raw.trim().to_ascii_uppercase();
    if names.iter().any(|(n, _)| *n == needle) {
        return true;
    }
    match raw.trim().parse::<u32>() {
        Ok(v) => (min..=max).contains(&v),
        Err(_) => false,
    }
}
const MONTHS: &[(&str, u32)] = &[("JAN",1),("FEB",2),("MAR",3),("APR",4),("MAY",5),("JUN",6),("JUL",7),("AUG",8),("SEP",9),("OCT",10),("NOV",11),("DEC",12)];
const WEEKDAYS: &[(&str, u32)] = &[("SUN",0),("MON",1),("TUE",2),("WED",3),("THU",4),("FRI",5),("SAT",6)];

Type guard

fn is_valid_cron_expr(expr: &str) -> bool {
    let fields: Vec<&str> = expr.split_whitespace().collect();
    fields.len() == 5
        && CronField::parse(fields[0], 0, 59, CronNameMap::none(), "minute").is_ok()
        && CronField::parse(fields[1], 0, 23, CronNameMap::none(), "hour").is_ok()
        && CronField::parse(fields[2], 1, 31, CronNameMap::none(), "day-of-month").is_ok()
        && CronField::parse(fields[3], 1, 12, CronNameMap::month(), "month").is_ok()
        && CronField::parse(fields[4], 0, 7, CronNameMap::weekday(), "day-of-week").is_ok()
}

Prevention

When it happens

Trigger: An automation task with `FREQ=CRON` whose EXPR contains an atom like `MONDAY` (only 3-letter names), `sept.`, `L`/`W`/`?`/`#` (Quartz-only syntax), `-5`, `1e2`, `24x`, or a stray character such as `9..15`. The atom is reached from single values, both endpoints of a range (`a-b`), and the base of steps (`base/step`).

Common situations: Pasting a Quartz/Spring cron string (6 fields with seconds, or `L`/`W`/`#`) into the automation config; typing full month/weekday names; copying a cron from a tutorial with a trailing dot or locale-specific characters; using 7-letter names like `OCTOBER`.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/1df34e8ae9be3894. Report an issue: GitHub.