Hmbown/CodeWhale · error · anyhow::Error

BYDAY cannot be empty for WEEKLY schedules

Error message

BYDAY cannot be empty for WEEKLY schedules

What it means

A defensive guard in the WEEKLY branch: BYDAY is present and parse_byday returned Ok with an empty weekday vector, meaning no day of week would ever match. In practice parse_byday rejects each empty/unknown token with 'Invalid BYDAY value', so reaching this requires a BYDAY value that tokenizes to zero entries — it protects next-run computation from looping forever on an unsatisfiable schedule.

Source

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

                    byday,
                    anchor_hour,
                    anchor_minute,
                })
            }
            AutomationFrequency::Weekly => {
                for key in parts.keys() {
                    if key != "FREQ" && key != "BYDAY" && key != "BYHOUR" && key != "BYMINUTE" {
                        bail!(
                            "Unsupported RRULE field '{key}' for WEEKLY. Allowed: FREQ,BYDAY,BYHOUR,BYMINUTE"
                        );
                    }
                }
                let byday_raw = parts
                    .get("BYDAY")
                    .ok_or_else(|| anyhow::anyhow!("WEEKLY schedules require BYDAY"))?;
                let byday = parse_byday(&byday_raw.to_ascii_uppercase())?;
                if byday.is_empty() {
                    bail!("BYDAY cannot be empty for WEEKLY schedules");
                }
                let byhour = parts
                    .get("BYHOUR")
                    .ok_or_else(|| anyhow::anyhow!("WEEKLY schedules require BYHOUR"))?
                    .parse::<u32>()
                    .context("Failed to parse BYHOUR")?;
                let byminute = parts
                    .get("BYMINUTE")
                    .ok_or_else(|| anyhow::anyhow!("WEEKLY schedules require BYMINUTE"))?
                    .parse::<u32>()
                    .context("Failed to parse BYMINUTE")?;

                if byhour > 23 {
                    bail!("BYHOUR must be between 0 and 23");
                }
                if byminute > 59 {
                    bail!("BYMINUTE must be between 0 and 59");
                }

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Provide at least one valid day code (MO,TU,WE,TH,FR,SA,SU): `FREQ=WEEKLY;BYDAY=MO,SU;...`.
  2. If no days are selected, either block submission in the UI or convert to a CRON/HOURLY rule instead.
  3. Lint WEEKLY rules for a non-empty, comma-separated, all-caps day list before parsing.

Example fix

// before
let rrule = format!("FREQ=WEEKLY;BYDAY={days};BYHOUR=9;BYMINUTE=0"); // days == "" -> error path

// after
if days.is_empty() {
    anyhow::bail!("select at least one weekday");
}
let rrule = format!("FREQ=WEEKLY;BYDAY={days};BYHOUR=9;BYMINUTE=0");
Defensive patterns

Strategy: validation

Validate before calling

if !rrule
    .split(';')
    .any(|p| p.trim().to_ascii_uppercase().starts_with("BYDAY="))
    || rrule.split(';').find(|p| p.trim().to_ascii_uppercase().starts_with("BYDAY=")).is_some_and(|p| p[6..].trim().is_empty())
{
    anyhow::bail!("WEEKLY schedules need at least one day: BYDAY=MO,TU,...");
}

Type guard

fn weekly_has_days(rrule: &str) -> bool {
    rrule.split(';').find_map(|p| p.trim().strip_prefix("BYDAY=").or_else(|| p.trim().strip_prefix("BYDAY=")))
        .is_some_and(|v| v.split(',').any(|t| !t.trim().is_empty()))
}

Try / catch

match AutomationSchedule::parse_rrule(&rrule) {
    Ok(s) => s,
    Err(e) if e.to_string().contains("BYDAY cannot be empty") => { /* require a weekday selection */ return Err(e) }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: parse_rrule("FREQ=WEEKLY;BYDAY=;BYHOUR=9;BYMINUTE=0") — a BYDAY key with an empty value generally trips 'Invalid BYDAY value' first; this bail catches any path where the day set ends up empty (future grammar changes, whitespace-only tokens).

Common situations: Config generators emitting `BYDAY=` when no days are selected; form submissions with an empty multi-select for weekdays.

Related errors


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