{"record":{"id":"c980cc5fcaa88296","repo":"Hmbown/CodeWhale","slug":"invalid-rrule-segment-item","errorCode":null,"errorMessage":"Invalid RRULE segment '{item}'","messagePattern":"Invalid RRULE segment '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":293,"sourceCode":"        byday: Vec<Weekday>,\n        byhour: u32,\n        byminute: u32,\n    },\n    Cron {\n        expr: String,\n    },\n}\n\nimpl AutomationSchedule {\n    pub fn parse_rrule(rrule: &str) -> Result<Self> {\n        let mut parts: BTreeMap<String, String> = BTreeMap::new();\n        for raw in rrule.split(';') {\n            let item = raw.trim();\n            if item.is_empty() {\n                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        };","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/automation_manager.rs#L275-L311","documentation":"AutomationSchedule::parse_rrule splits the rule string on ';' and requires every non-empty trimmed segment to contain '='. A segment without '=' cannot be a KEY=VALUE part, so parsing stops immediately with the offending segment named in the message.","triggerScenarios":"Passing an RRULE like `FREQ=WEEKLY;MO,WE;BYHOUR=9` (bare day list without the BYDAY= key), `FREQ WEEKLY` (wrong separator), or a trailing scrap like `FREQ=HOURLY;INTERVAL=2;;junk` to parse_rrule.","commonSituations":"Hand-writing RRULE strings in automation config or the automation tool; concatenating segments without the '='; copying RRULE text from calendar apps that omit values for empty parts.","solutions":["Fix the segment to KEY=VALUE form, e.g. `FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=30`.","Split and lint each `;`-separated part with `part.split_once('=')` before submitting the schedule.","Use the documented grammar from crates/tui/src/tools/automation.rs (ONCE/HOURLY/WEEKLY/CRON forms) as the template."],"exampleFix":"// before\nlet sched = AutomationSchedule::parse_rrule(\"FREQ=WEEKLY;MO,WE\")?; // bails: segment 'MO,WE'\n\n// after\nlet sched = AutomationSchedule::parse_rrule(\"FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=30\")?;","handlingStrategy":"validation","validationCode":"fn rrule_segments_wellformed(rrule: &str) -> bool {\n    rrule.split(';')\n        .map(str::trim)\n        .filter(|s| !s.is_empty())\n        .all(|s| s.split_once('=').is_some())\n}","typeGuard":"fn is_parseable_rrule_shape(rrule: &str) -> bool {\n    rrule.split(';').filter(|s| !s.trim().is_empty()).all(|s| s.split_once('=').is_some())\n        && rrule.to_ascii_uppercase().contains(\"FREQ=\")\n}","tryCatchPattern":"match AutomationSchedule::parse_rrule(&rrule) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"Invalid RRULE segment\") => { /* show KEY=VALUE grammar hint */ return Err(e) }\n    Err(e) => return Err(e),\n}","preventionTips":["Build RRULEs from typed parts (enum freq, u32 interval, Weekday vec) instead of string concatenation.","Lint every ';'-separated segment for '=' before submitting user input.","Reject empty/junk segments early in the UI with the supported grammar."],"tags":["rrule","automation","schedule","parsing"],"backgroundTag":"rrule-malformed-segment","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}