Hmbown/CodeWhale · error · anyhow::Error

Unsupported RRULE field

Error message

Unsupported RRULE field '{key}' for HOURLY. Allowed: FREQ,INTERVAL,BYDAY,BYHOUR,BYMINUTE

What it means

For FREQ=HOURLY, the parser whitelists only FREQ, INTERVAL, BYDAY, BYHOUR, and BYMINUTE. Any other RRULE key (e.g. BYDAYSET, COUNT, UNTIL, BYMONTH) makes it reject the rule rather than silently ignore it. This keeps hourly schedules deterministic and free of unsupported semantics.

Solutions

  1. Remove the unsupported key from the RRULE string
  2. Replace COUNT/UNTIL-based limits with the automation tool's own end conditions
  3. Fix typos so keys are exactly FREQ, INTERVAL, BYDAY, BYHOUR, or BYMINUTE (uppercase)

Example fix

// before
RRULE:FREQ=HOURLY;INTERVAL=2;COUNT=10
// after
RRULE:FREQ=HOURLY;INTERVAL=2
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = ["FREQ","INTERVAL","BYDAY","BYHOUR","BYMINUTE"];
for (const kv of rule.split(';').slice(1)) {
  const key = kv.split('=')[0].trim().toUpperCase();
  if (!ALLOWED.includes(key)) throw new Error(`Unsupported RRULE field ${key} for HOURLY`);
}

Try / catch

try {
  parse_rrule(rule)?;
} catch e if e.to_string().contains("Unsupported RRULE field") {
  eprintln!("{e}: strip unknown keys or use CRON for richer schedules");
}

Prevention

When it happens

Trigger: Parsing 'RRULE:FREQ=HOURLY;COUNT=5' or 'RRULE:FREQ=HOURLY;INTERVAL=2;BYMONTH=3' — any key outside the whitelist triggers the error.

Common situations: Pasting a full RFC-5545 RRULE from a calendar app that includes COUNT/UNTIL/WKST; typos like BYHOURS or INTERVALS.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/27acee85a982526e. Report an issue: GitHub.

Appendix: source

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

            Some("HOURLY") => AutomationFrequency::Hourly,
            Some("WEEKLY") => AutomationFrequency::Weekly,
            Some("CRON") => return parse_cron_schedule(&parts),
            Some(other) => {
                bail!("Unsupported RRULE FREQ '{other}'. Supported: ONCE, HOURLY, WEEKLY, and CRON")
            }
            None => bail!("RRULE must include FREQ"),
        };

        match freq {
            AutomationFrequency::Hourly => {
                for key in parts.keys() {
                    if key != "FREQ"
                        && key != "INTERVAL"
                        && key != "BYDAY"
                        && key != "BYHOUR"
                        && key != "BYMINUTE"
                    {
                        bail!(
                            "Unsupported RRULE field '{key}' for HOURLY. Allowed: FREQ,INTERVAL,BYDAY,BYHOUR,BYMINUTE"
                        );
                    }
                }
                let interval_hours = parts
                    .get("INTERVAL")
                    .map(|v| v.parse::<u32>())
                    .transpose()
                    .context("Failed to parse INTERVAL")?
                    .unwrap_or(1);
                if interval_hours == 0 {
                    bail!("INTERVAL must be >= 1 for HOURLY schedules");
                }
                let byday = parts
                    .get("BYDAY")
                    .map(|value| parse_byday(&value.to_ascii_uppercase()))
                    .transpose()?;
                let anchor_hour = parts

View on GitHub (pinned to 73e0f67d83)