Hmbown/CodeWhale · error · anyhow::Error

CRON {field_name} range start must be <= end

Error message

CRON {field_name} range start must be <= end

What it means

Range atoms must satisfy start <= end after name/number resolution; cron-style wraparound ranges are not supported. Overnight hour ranges like 20-6 and day-of-week ranges like SAT-SUN (6-0) fail because names resolve to numbers before the comparison.

Source

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

                let step = step
                    .trim()
                    .parse::<u32>()
                    .with_context(|| format!("Failed to parse CRON {field_name} step"))?;
                if step == 0 {
                    bail!("CRON {field_name} step must be >= 1");
                }
                (base.trim(), step)
            } else {
                (part, 1)
            };

            let range = if base == "*" {
                (min, max)
            } else if let Some((start, end)) = base.split_once('-') {
                let start = parse_cron_atom(start.trim(), min, max, names, field_name)?;
                let end = parse_cron_atom(end.trim(), min, max, names, field_name)?;
                if start > end {
                    bail!("CRON {field_name} range start must be <= end");
                }
                (start, end)
            } else {
                let start = parse_cron_atom(base, min, max, names, field_name)?;
                if part.contains('/') {
                    (start, max)
                } else {
                    (start, start)
                }
            };

            let mut current = range.0;
            while current <= range.1 {
                if !values.contains(&current) {
                    values.push(current);
                }
                let Some(next) = current.checked_add(step) else {
                    break;

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Split wrapping ranges into two list items: '0 0-6,20-23 * * *'
  2. For SAT-SUN write '0 0 * * 0,6' or '6-7' (7 normalizes to Sunday 0)
  3. Keep all ranges ascending
  4. Dry-run parse_rrule before activating

Example fix

// before (wrapping overnight range unsupported)
rrule = "FREQ=CRON;EXPR=0 20-6 * * *"

// after
rrule = "FREQ=CRON;EXPR=0 20-23,0-6 * * *"
Defensive patterns

Strategy: validation

Validate before calling

fn cron_expr_valid(expr: &str) -> bool {
    AutomationSchedule::parse_rrule(&format!("FREQ=CRON;EXPR={expr}")).is_ok()
}

Prevention

When it happens

Trigger: EXPR='0 20-6 * * *' (overnight hours); EXPR='0 0 * * 6-0' (SAT-SUN wrap); any reversed numeric or name range in any field.

Common situations: Porting expressions from schedulers that accept wrapping ranges; overnight maintenance windows written naturally as evening-to-morning.

Related errors


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