{"record":{"id":"26d1205fe7dbdbfd","repo":"Hmbown/CodeWhale","slug":"invalid-byday-value-other","errorCode":null,"errorMessage":"Invalid BYDAY value '{other}'","messagePattern":"Invalid BYDAY value '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":590,"sourceCode":"fn resolve_local_datetime<Tz: TimeZone>(\n    timezone: &Tz,\n    naive: NaiveDateTime,\n) -> Option<DateTime<Tz>> {\n    timezone.from_local_datetime(&naive).earliest()\n}\n\nfn parse_byday(value: &str) -> Result<Vec<Weekday>> {\n    let mut days = Vec::new();\n    for token in value.split(',') {\n        let day = match token.trim().to_ascii_uppercase().as_str() {\n            \"MO\" => Weekday::Mon,\n            \"TU\" => Weekday::Tue,\n            \"WE\" => Weekday::Wed,\n            \"TH\" => Weekday::Thu,\n            \"FR\" => Weekday::Fri,\n            \"SA\" => Weekday::Sat,\n            \"SU\" => Weekday::Sun,\n            other => bail!(\"Invalid BYDAY value '{other}'\"),\n        };\n        if !days.contains(&day) {\n            days.push(day);\n        }\n    }\n    Ok(days)\n}\n\nfn parse_once_schedule(parts: &BTreeMap<String, String>) -> Result<AutomationSchedule> {\n    for key in parts.keys() {\n        if key != \"FREQ\" && key != \"AT\" {\n            bail!(\"Unsupported RRULE field '{key}' for ONCE. Allowed: FREQ,AT\");\n        }\n    }\n    let raw_at = parts\n        .get(\"AT\")\n        .ok_or_else(|| anyhow::anyhow!(\"ONCE schedules require AT\"))?;\n    let at = parse_once_at(raw_at)?;","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/automation_manager.rs#L572-L608","documentation":"parse_byday rejects any BYDAY token that is not one of the two-letter codes MO TU WE TH FR SA SU after trimming and uppercasing. It fires while parsing HOURLY or WEEKLY rrules, before any schedule object is built. Ordinal prefixes (1MO, -1SU), full day names, and numeric weekday codes are all unsupported.","triggerScenarios":"AutomationSchedule::parse_rrule(\"FREQ=WEEKLY;BYDAY=MONDAY;BYHOUR=9;BYMINUTE=0\") (full word); BYDAY=1 (numeric code); BYDAY=MO;TU (wrong separator); a stray token like BYDAY=MO,XX.","commonSituations":"Copying RRULE syntax from iCalendar examples that allow ordinals or full names; assuming ISO numeric weekday codes; simple typos in hand-written rules.","solutions":["Use exactly the two-letter codes: FREQ=WEEKLY;BYDAY=MO,WE,FR","Comma-separate multiple days (surrounding whitespace is trimmed)","Remove ordinal prefixes like 1MO or -1SU; this scheduler has no nth-weekday concept","Validate with parse_rrule before persisting the rrule"],"exampleFix":"// before\nrrule = \"FREQ=WEEKLY;BYDAY=MON,WED;BYHOUR=9;BYMINUTE=0\"\n\n// after\nrrule = \"FREQ=WEEKLY;BYDAY=MO,WE;BYHOUR=9;BYMINUTE=0\"","handlingStrategy":"validation","validationCode":"fn valid_byday(value: &str) -> bool {\n    const OK: [&str; 7] = [\"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\"];\n    !value.is_empty()\n        && value.split(',').all(|t| OK.contains(&t.trim().to_ascii_uppercase().as_str()))\n}","typeGuard":"fn is_valid_byday_rrule(rrule: &str) -> bool {\n    AutomationSchedule::parse_rrule(rrule).is_ok()\n}","tryCatchPattern":null,"preventionTips":["Offer BYDAY as a weekday picker instead of free text","Validate the rrule with parse_rrule at the tool boundary before create/update","Normalize input to two-letter uppercase codes early","Document that ordinals (1MO) and numeric codes are unsupported"],"tags":["rust","rrule","byday","validation","weekday"],"backgroundTag":"rrule-invalid-byday-value","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}