Hmbown/CodeWhale · error

WEEKLY schedules require BYDAY

Error message

WEEKLY schedules require BYDAY

What it means

AutomationSchedule::parse_rrule validates RRULE strings for scheduled automations. FREQ=WEEKLY requires BYDAY (two-letter day codes like MO,WE) to say which weekdays fire; WEEKLY allows only the fields FREQ,BYDAY,BYHOUR,BYMINUTE, and a string without the BYDAY key is rejected with this error at parse time, before any schedule is stored.

Source

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

                }
                Ok(Self::Hourly {
                    interval_hours,
                    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");
                }

View on GitHub (pinned to 8880682c63)

Solutions

  1. Add BYDAY with one or more day codes: FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=30
  2. Use uppercase field names exactly as FREQ/BYDAY/BYHOUR/BYMINUTE; any other key is rejected with its own 'Unsupported RRULE field' error
  3. Validate the RRULE with parse_rrule before persisting or sending it to the automation tool

Example fix

// before
let rrule = "FREQ=WEEKLY;BYHOUR=9;BYMINUTE=30";
// after
let rrule = "FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=30";
Defensive patterns

Strategy: validation

Validate before calling

let parts: std::collections::BTreeMap<&str, &str> = rrule
    .split(';')
    .filter_map(|kv| kv.split_once('='))
    .collect();
if parts.get("FREQ").copied() == Some("WEEKLY") && !parts.contains_key("BYDAY") {
    anyhow::bail!("add BYDAY, e.g. FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=30");
}

Type guard

fn is_valid_weekly_rrule(rrule: &str) -> bool {
    let parts: std::collections::BTreeMap<String, String> = rrule
        .split(';')
        .filter_map(|kv| kv.split_once('='))
        .map(|(k, v)| (k.to_ascii_uppercase(), v.to_string()))
        .collect();
    parts.get("FREQ").map(String::as_str) == Some("WEEKLY")
        && ["BYDAY", "BYHOUR", "BYMINUTE"].iter().all(|k| parts.contains_key(*k))
        && parts.keys().all(|k| matches!(k.as_str(), "FREQ" | "BYDAY" | "BYHOUR" | "BYMINUTE"))
}

Prevention

When it happens

Trigger: Creating or updating an automation whose rrule is e.g. 'FREQ=WEEKLY;BYHOUR=9;BYMINUTE=30' (BYDAY omitted), passed via the automation tool create/update action or any caller of AutomationSchedule::parse_rrule.

Common situations: Hand-written RRULEs adapted from HOURLY examples (which make BYDAY optional); model-generated schedules copying the weekly template incompletely; forgetting that weekly needs all three of BYDAY/BYHOUR/BYMINUTE.

Related errors


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