{"record":{"id":"0bfc0206329ec9a0","repo":"Hmbown/CodeWhale","slug":"unsupported-rrule-freq-other-supported-once","errorCode":null,"errorMessage":"Unsupported RRULE FREQ '{other}'. Supported: ONCE, HOURLY, WEEKLY, and CRON","messagePattern":"Unsupported RRULE FREQ '(.+?)'\\. Supported: ONCE, HOURLY, WEEKLY, and CRON","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":308,"sourceCode":"                continue;\n            }\n            let Some((k, v)) = item.split_once('=') else {\n                bail!(\"Invalid RRULE segment '{item}'\");\n            };\n            parts.insert(k.trim().to_ascii_uppercase(), v.trim().to_string());\n        }\n\n        let freq = match parts\n            .get(\"FREQ\")\n            .map(|value| value.trim().to_ascii_uppercase())\n            .as_deref()\n        {\n            Some(\"ONCE\") => return parse_once_schedule(&parts),\n            Some(\"HOURLY\") => AutomationFrequency::Hourly,\n            Some(\"WEEKLY\") => AutomationFrequency::Weekly,\n            Some(\"CRON\") => return parse_cron_schedule(&parts),\n            Some(other) => {\n                bail!(\"Unsupported RRULE FREQ '{other}'. Supported: ONCE, HOURLY, WEEKLY, and CRON\")\n            }\n            None => bail!(\"RRULE must include FREQ\"),\n        };\n\n        match freq {\n            AutomationFrequency::Hourly => {\n                for key in parts.keys() {\n                    if key != \"FREQ\"\n                        && key != \"INTERVAL\"\n                        && key != \"BYDAY\"\n                        && key != \"BYHOUR\"\n                        && key != \"BYMINUTE\"\n                    {\n                        bail!(\n                            \"Unsupported RRULE field '{key}' for HOURLY. Allowed: FREQ,INTERVAL,BYDAY,BYHOUR,BYMINUTE\"\n                        );\n                    }\n                }","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/automation_manager.rs#L290-L326","documentation":"parse_rrule accepts only FREQ values ONCE, HOURLY, WEEKLY, and CRON (case-insensitive). Any other FREQ — the RFC 5545 values DAILY, MONTHLY, YEARLY, MINUTELY, SECONDLY included — is rejected because the scheduler does not implement them.","triggerScenarios":"Calling parse_rrule with `FREQ=DAILY;...`, `FREQ=MONTHLY;...`, or `FREQ=MINUTELY` (even otherwise-valid RFC 5545 rules), or a typo like `FREQ=WEEKLYY` after uppercasing.","commonSituations":"Porting calendar RRULEs (which commonly use DAILY/MONTHLY) into codewhale automations; assuming full RFC 5545 coverage; copy-paste from iCalendar files.","solutions":["Express DAILY as `FREQ=HOURLY;INTERVAL=24;BYHOUR=9;BYMINUTE=0` or as `FREQ=CRON;EXPR=0 9 * * *`.","Use `FREQ=CRON;EXPR=...` with a standard 5-field local-time cron for MONTHLY/YEARLY/complex patterns.","Re-read the grammar in the automation tool description (crates/tui/src/tools/automation.rs) before writing the rule."],"exampleFix":"// before\nlet sched = AutomationSchedule::parse_rrule(\"FREQ=DAILY;BYHOUR=9\")?; // bails: Unsupported FREQ 'DAILY'\n\n// after\nlet sched = AutomationSchedule::parse_rrule(\"FREQ=CRON;EXPR=0 9 * * *\")?;","handlingStrategy":"validation","validationCode":"const SUPPORTED_FREQ: &[&str] = &[\"ONCE\", \"HOURLY\", \"WEEKLY\", \"CRON\"];\nlet freq = rrule\n    .split(';')\n    .find_map(|p| p.trim().strip_prefix(\"FREQ=\").or_else(|| p.trim().strip_prefix(\"freq=\")))\n    .map(|f| f.trim().to_ascii_uppercase());\nif !freq.as_deref().is_some_and(|f| SUPPORTED_FREQ.contains(&f)) {\n    anyhow::bail!(\"use FREQ=ONCE|HOURLY|WEEKLY|CRON; express DAILY via INTERVAL=24 or CRON\");\n}","typeGuard":"fn supported_freq(rrule: &str) -> Option<&'static str> {\n    let f = rrule.split(';').find(|p| p.trim().to_ascii_uppercase().starts_with(\"FREQ=\"))?;\n    let v = f.trim()[5..].to_ascii_uppercase();\n    match v.as_str() {\n        \"ONCE\" | \"HOURLY\" | \"WEEKLY\" | \"CRON\" => Some(match v.as_str() { \"ONCE\" => \"ONCE\", \"HOURLY\" => \"HOURLY\", \"WEEKLY\" => \"WEEKLY\", _ => \"CRON\" }),\n        _ => None,\n    }\n}","tryCatchPattern":"match AutomationSchedule::parse_rrule(&rrule) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"Unsupported RRULE FREQ\") => { /* offer CRON translation */ return Err(e) }\n    Err(e) => return Err(e),\n}","preventionTips":["Do not assume RFC 5545 coverage: only ONCE, HOURLY, WEEKLY, CRON exist.","Translate DAILY to FREQ=HOURLY;INTERVAL=24 or a CRON expr at authoring time.","Show the supported FREQ list in schedule-creation UIs and autocomplete to it."],"tags":["rrule","automation","schedule","unsupported-frequency"],"backgroundTag":"rrule-unsupported-frequency","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}