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
- Rewrite EXPR with exactly 5 space-separated fields: minute hour day-of-month month day-of-week.
- Use only 3-letter names (MON, FRI, JAN, OCT) or plain integers — e.g. `EXPR=0 9 * * MON-FRI` instead of `0 9 ? * MONDAY *`.
- 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`).
- 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
- Validate the CRON EXPR in the UI/script before saving the automation task so the user gets field-level feedback.
- Lint pasted cron strings for Quartz-only tokens (L, W, ?, #) and a 6th seconds field.
- Offer a cron preview/next-run computation at input time — it forces full parsing early.
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
- CRON schedules require EXPR
- Codewhale stream-json line {line_number} was not an object
- WEEKLY schedules require BYDAY
- WEEKLY schedules require BYHOUR
- WEEKLY schedules require BYMINUTE
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/1df34e8ae9be3894.
Report an issue: GitHub.